FileDocCategorySizeDatePackage
DTMDocumentImpl.javaAPI DocJava SE 5 API95629Fri Aug 26 14:56:00 BST 2005com.sun.org.apache.xml.internal.dtm.ref

DTMDocumentImpl

public class DTMDocumentImpl extends Object implements LexicalHandler, ContentHandler, DTM
This is the implementation of the DTM document interface. It receives requests from an XML content handler similar to that of an XML DOM or SAX parser to store information from the xml document in an array based dtm table structure. This informtion is used later for document navigation, query, and SAX event dispatch functions. The DTM can also be used directly as a document composition model for an application. The requests received are:
  • initiating DTM to set the doc handle
  • resetting DTM for data structure reuse
  • hinting the end of document to adjust the end of data structure pointers
  • createnodes (element, comment, text, attribute, ....)
  • hinting the end of an element to patch parent and siblings
  • setting application provided symbol name stringpool data structures

State: In progress!!

%REVIEW% I _think_ the SAX convention is that "no namespace" is expressed as "" rather than as null (which is the DOM's convention). What should DTM expect? What should it do with the other?

Origin: the implemention is a composite logic based on the DTM of XalanJ1 and DocImpl, DocumentImpl, ElementImpl, TextImpl, etc. of XalanJ2

Fields Summary
protected static final byte
DOCHANDLE_SHIFT
protected static final int
NODEHANDLE_MASK
protected static final int
DOCHANDLE_MASK
int
m_docHandle
int
m_docElement
int
currentParent
int
previousSibling
protected int
m_currentNode
private boolean
previousSiblingWasParent
int[]
gotslot
private boolean
done
boolean
m_isError
private final boolean
DEBUG
protected String
m_documentBaseURI
The document base URI.
private IncrementalSAXSource
m_incrSAXSource
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.
ChunkedIntArray
nodes
private FastStringBuffer
m_char
private int
m_char_current_start
private DTMStringPool
m_localNames
private DTMStringPool
m_nsNames
private DTMStringPool
m_prefixNames
private ExpandedNameTable
m_expandedNames
private XMLStringFactory
m_xsf
static final String[]
fixednames
fixednames
Constructors Summary
public DTMDocumentImpl(DTMManager mgr, int documentNumber, DTMWSFilter whiteSpaceFilter, XMLStringFactory xstringfactory)
Construct a DTM.

param
documentNumber the ID number assigned to this document. It will be shifted up into the high bits and returned as part of all node ID numbers, so those IDs indicate which document they came from as well as a location within the document. It is the DTMManager's responsibility to assign a unique number to each document.



                                                                             
            
                                
                                
                initDocument(documentNumber);	 // clear nodes and document handle
                m_xsf = xstringfactory;
        
Methods Summary
voidappendAttribute(int namespaceIndex, int localNameIndex, int prefixIndex, boolean isID, int m_char_current_start, int contentLength)
Append an Attribute child at the current insertion point. Assumes that the symbols (namespace URI, local name, and prefix) have already been added to the pools, and that the content has already been appended to m_char. Note that the attribute's content has been flattened into a single string; DTM does _NOT_ attempt to model the details of entity references within attribute values.

param
namespaceIndex int Index within the namespaceURI string pool
param
localNameIndex int Index within the local name string pool
param
prefixIndex int Index within the prefix string pool
param
isID boolean True if this attribute was declared as an ID (for use in supporting getElementByID).
param
m_char_current_start int Starting offset of node's content in m_char.
param
contentLength int Length of node's content in m_char.

    // %TBD% isID is not currently honored.

    // W0  High:  Namespace  Low:  Node Type
    int w0 = ATTRIBUTE_NODE | namespaceIndex<<16;

    // W1:  Parent
    int w1 = currentParent;
    // W2:  Next (not yet resolved)
    int w2 = 0;
    // W3:  Tagname high: prefix Low: local name
    int w3 = localNameIndex | prefixIndex<<16;
    /**/System.out.println("set w3="+w3+" "+(w3>>16)+"/"+(w3&0xffff));
    // Add node
    int ourslot = appendNode(w0, w1, w2, w3);
    previousSibling = ourslot;	// Should attributes be previous siblings

    // Attribute's content is currently appended as a Text Node

    // W0: Node Type
    w0 = TEXT_NODE;
    // W1: Parent
    w1 = ourslot;
    // W2: Start Position within buffer
    w2 = m_char_current_start;
    // W3: Length
    w3 = contentLength;
    appendNode(w0, w1, w2, w3);

    // Attrs are Parents
    previousSiblingWasParent = true;
    return ;//(m_docHandle | ourslot);
  
public voidappendChild(int newChild, boolean clone, boolean cloneDepth)
Append a child to the end of the child list of the current node. Please note that the node is always cloned if it is owned by another document.

%REVIEW% "End of the document" needs to be defined more clearly. Does it become the last child of the Document? Of the root element?

param
newChild Must be a valid new node handle.
param
clone true if the child should be cloned into the document.
param
cloneDepth if the clone argument is true, specifies that the clone should include all it's children.

                boolean sameDoc = ((newChild & DOCHANDLE_MASK) == m_docHandle);
                if (clone || !sameDoc) {

                } else {

                }
        
voidappendComment(int m_char_current_start, int contentLength)
Append a comment child at the current insertion point. Assumes that the actual content of the comment has previously been appended to the m_char buffer (shared with the builder).

param
m_char_current_start int Starting offset of node's content in m_char.
param
contentLength int Length of node's content in m_char.

    // create a Comment Node
    // %TBD% may be possible to combine with appendNode()to replace the next chunk of code
    int w0 = COMMENT_NODE;
    // W1: Parent
    int w1 = currentParent;
    // W2: Start position within m_char
    int w2 = m_char_current_start;
    // W3: Length of the full string
    int w3 = contentLength;

    int ourslot = appendNode(w0, w1, w2, w3);
    previousSibling = ourslot;
  
voidappendEndDocument()
All appends to this document have finished; do whatever final cleanup is needed.

    done = true;
    // %TBD% may need to notice the last slot number and slot count to avoid
    // residual data from provious use of this DTM
  
voidappendEndElement()
Terminate the element currently acting as an insertion point. Subsequent insertions will occur as the last child of this element's parent.

    // pop up the stacks

    if (previousSiblingWasParent)
      nodes.writeEntry(previousSibling, 2, NULL);

    // Pop parentage
    previousSibling = currentParent;
    nodes.readSlot(currentParent, gotslot);
    currentParent = gotslot[1] & 0xFFFF;

    // The element just being finished will be
    // the previous sibling for the next operation
    previousSiblingWasParent = true;

    // Pop a level of namespace table
    // namespaceTable.removeLastElem();
  
voidappendNSDeclaration(int prefixIndex, int namespaceIndex, boolean isID)
Append a Namespace Declaration child at the current insertion point. Assumes that the symbols (namespace URI and prefix) have already been added to the pools

param
prefixIndex: Index within the prefix string pool
param
namespaceIndex: Index within the namespaceURI string pool
param
isID: If someone really insists on writing a bad DTD, it is theoretically possible for a namespace declaration to also be declared as being a node ID. I don't really want to support that stupidity, but I'm not sure we can refuse to accept it.

    // %REVIEW% I'm assigning this node the "namespace for namespaces"
    // which the DOM defined. It is expected that the Namespace spec will
    // adopt this as official. It isn't strictly needed since it's implied
    // by the nodetype, but for now...

    // %REVIEW% Prefix need not be recorded; it's implied too. But
    // recording it might simplify the design.

    // %TBD% isID is not currently honored.

    final int namespaceForNamespaces=m_nsNames.stringToIndex("http://www.w3.org/2000/xmlns/");

    // W0  High:  Namespace  Low:  Node Type
    int w0 = NAMESPACE_NODE | (m_nsNames.stringToIndex("http://www.w3.org/2000/xmlns/")<<16);

    // W1:  Parent
    int w1 = currentParent;
    // W2:  CURRENTLY UNUSED -- It's next-sib in attrs, but we have no kids.
    int w2 = 0;
    // W3:  namespace name
    int w3 = namespaceIndex;
    // Add node
    int ourslot = appendNode(w0, w1, w2, w3);
    previousSibling = ourslot;	// Should attributes be previous siblings
    previousSiblingWasParent = false;
    return ;//(m_docHandle | ourslot);
  
private final intappendNode(int w0, int w1, int w2, int w3)
Wrapper for ChunkedIntArray.append, to automatically update the previous sibling's "next" reference (if necessary) and periodically wake a reader who may have encountered incomplete data and entered a wait state.

param
w0 int As in ChunkedIntArray.append
param
w1 int As in ChunkedIntArray.append
param
w2 int As in ChunkedIntArray.append
param
w3 int As in ChunkedIntArray.append
return
int As in ChunkedIntArray.append
see
ChunkedIntArray.append

                // A decent compiler may inline this.
                int slotnumber = nodes.appendSlot(w0, w1, w2, w3);

                if (DEBUG) System.out.println(slotnumber+": "+w0+" "+w1+" "+w2+" "+w3);

                if (previousSiblingWasParent)
                        nodes.writeEntry(previousSibling,2,slotnumber);

                previousSiblingWasParent = false;	// Set the default; endElement overrides

                return slotnumber;
        
voidappendStartDocument()
Starting a new document. Perform any resets/initialization not already handled.


    // %TBD% reset slot 0 to indicate ChunkedIntArray reuse or wait for
    //       the next initDocument().
    m_docElement = NULL;	 // reset nodeHandle to the root of the actual dtm doc content
    initDocument(0);
  
voidappendStartElement(int namespaceIndex, int localNameIndex, int prefixIndex)
Append an Element child at the current insertion point. This Element then _becomes_ the insertion point; subsequent appends become its lastChild until an appendEndElement() call is made. Assumes that the symbols (local name, namespace URI and prefix) have already been added to the pools Note that this _only_ handles the Element node itself. Attrs and namespace nodes are unbundled in the ContentHandler layer and appended separately.

param
namespaceIndex: Index within the namespaceURI string pool
param
localNameIndex Index within the local name string pool
param
prefixIndex: Index within the prefix string pool

                // do document root node creation here on the first element, create nodes for
                // this element and its attributes, store the element, namespace, and attritute
                // name indexes to the nodes array, keep track of the current node and parent
                // element used

                // W0  High:  Namespace  Low:  Node Type
                int w0 = (namespaceIndex << 16) | ELEMENT_NODE;
                // W1: Parent
                int w1 = currentParent;
                // W2: Next  (initialized as 0)
                int w2 = 0;
                // W3: Tagname high: prefix Low: local name
                int w3 = localNameIndex | prefixIndex<<16;
                /**/System.out.println("set w3="+w3+" "+(w3>>16)+"/"+(w3&0xffff));

                //int ourslot = nodes.appendSlot(w0, w1, w2, w3);
                int ourslot = appendNode(w0, w1, w2, w3);
                currentParent = ourslot;
                previousSibling = 0;

                // set the root element pointer when creating the first element node
                if (m_docElement == NULL)
                        m_docElement = ourslot;
  
public voidappendTextChild(java.lang.String str)
Append a text node child that will be constructed from a string, to the end of the document.

%REVIEW% "End of the document" needs to be defined more clearly. Does it become the last child of the Document? Of the root element?

param
str Non-null reference to a string.

                // ###shs Think more about how this differs from createTextNode
          //%TBD%
        
voidappendTextChild(int m_char_current_start, int contentLength)
Append a text child at the current insertion point. Assumes that the actual content of the text has previously been appended to the m_char buffer (shared with the builder).

param
m_char_current_start int Starting offset of node's content in m_char.
param
contentLength int Length of node's content in m_char.

    // create a Text Node
    // %TBD% may be possible to combine with appendNode()to replace the next chunk of code
    int w0 = TEXT_NODE;
    // W1: Parent
    int w1 = currentParent;
    // W2: Start position within m_char
    int w2 = m_char_current_start;
    // W3: Length of the full string
    int w3 = contentLength;

    int ourslot = appendNode(w0, w1, w2, w3);
    previousSibling = ourslot;
  
public voidcharacters(char[] ch, int start, int length)

    // Actually creating the text node is handled by
    // processAccumulatedText(); here we just accumulate the
    // characters into the buffer.
    m_char.append(ch,start,length);
  
public voidcomment(char[] ch, int start, int length)

    processAccumulatedText();

    m_char.append(ch,start,length); // Single-string value
    appendComment(m_char_current_start,length);
    m_char_current_start+=length;
  
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.
throws
org.xml.sax.SAXException

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

public voiddocumentRegistration()
A dummy routine to satisify the abstract interface. If the DTM implememtation that extends the default base requires notification of registration, they can override this method.

   
public voiddocumentRelease()
A dummy routine to satisify the abstract interface. If the DTM implememtation that extends the default base requires notification when the document is being released, they can override this method

   
public voidendCDATA()

    // No-op in DTM
  
public voidendDTD()

    // No-op in DTM
  
public voidendDocument()

    // May need to tell the low-level builder code to pop up a level.
    // There _should't_ be any significant pending text at this point.
    appendEndDocument();
  
public voidendElement(java.lang.String namespaceURI, java.lang.String localName, java.lang.String qName)

    processAccumulatedText();
    // No args but we do need to tell the low-level builder code to
    // pop up a level.
    appendEndElement();
  
public voidendEntity(java.lang.String name)

    // No-op in DTM
  
public voidendPrefixMapping(java.lang.String prefix)

    // No-op
  
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.

                int nsIndex = m_nsNames.stringToIndex(namespaceURI),
                                                                        nameIndex = m_localNames.stringToIndex(name);
                nodeHandle &= NODEHANDLE_MASK;
                nodes.readSlot(nodeHandle, gotslot);
                short type = (short) (gotslot[0] & 0xFFFF);
                // If nodeHandle points to element next slot would be first attribute
                if (type == ELEMENT_NODE)
                        nodeHandle++;
                // Iterate through Attribute Nodes
                while (type == ATTRIBUTE_NODE) {
                        if ((nsIndex == (gotslot[0] << 16)) && (gotslot[3] == nameIndex))
                                return nodeHandle | m_docHandle;
                        // Goto next sibling
                        nodeHandle = gotslot[2];
                        nodes.readSlot(nodeHandle, gotslot);
                }
                return NULL;
        
public com.sun.org.apache.xml.internal.dtm.DTMAxisIteratorgetAxisIterator(int axis)
This is a shortcut to the iterators that implement the supported XPath axes (only namespace::) is not supported. Returns a bare-bones iterator that must be initialized with a start node (using iterator.setStartNode()).

param
axis One of Axes.ANCESTORORSELF, etc.
return
A DTMAxisIterator, or null if the given axis isn't supported.

    // %TBD%
    return null;
  
public com.sun.org.apache.xml.internal.dtm.DTMAxisTraversergetAxisTraverser(int axis)
This returns a stateless "traverser", that can navigate over an XPath axis, though not in document order.

param
axis One of Axes.ANCESTORORSELF, etc.
return
A DTMAxisIterator, or null if the given axis isn't supported.

    return null;
  
com.sun.org.apache.xml.internal.utils.FastStringBuffergetContentBuffer()
Get a reference pointer to the content-text repository

return
FastStringBuffer reference to an instance of buffer

                 return m_char;
         
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.

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

    if (m_incrSAXSource instanceof IncrementalSAXSource_Filter)
      return (ContentHandler) m_incrSAXSource;
    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 null;
  
public org.xml.sax.ext.DeclHandlergetDeclHandler()
Return this DTM's DeclHandler.

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


    return null;
  
public intgetDocument()
Given a node handle, find the owning document node.

param
nodeHandle the id of the node.
return
int Node handle of document, which should always be valid.

                return m_docHandle;
        
public booleangetDocumentAllDeclarationsProcessed()
Return an indication of whether the processor has read the complete DTD. Its value is a boolean. If it is false, then certain properties (indicated in their descriptions below) may be unknown. If it is true, those properties are never unknown.

return
true if all declarations were processed {}; false otherwise.

return false;
public java.lang.StringgetDocumentBaseURI()
Return the base URI of the document entity. If it is not known (because the document was parsed from a socket connection or from standard input, for example), the value of this property is unknown.

return
the document base URI String object or null if unknown.


          return m_documentBaseURI;
        
public java.lang.StringgetDocumentEncoding(int nodeHandle)
Return the name of the character encoding scheme in which the document entity is expressed.

param
nodeHandle The node id, which can be any valid node handle.
return
the document encoding String object.

return null;
public intgetDocumentRoot()
Returns the root element of the document.

return
nodeHandle to the Document Root.

                return (m_docHandle | m_docElement);
        
public intgetDocumentRoot(int nodeHandle)
Given a node handle, find the owning document node. This has the DTM semantics; a Document node is its own owner.

%REVIEW% Since this is DOM-specific, it may belong at the DOM binding layer. Included here as a convenience function and to aid porting of DOM code to DTM.

param
nodeHandle the id of the node.
return
int Node handle of owning document, or NULL if the nodeHandle is a document.

                // Assumption that Document Node is always in 0 slot
                if ((nodeHandle & NODEHANDLE_MASK) == 0)
                        return NULL;
                return (nodeHandle & DOCHANDLE_MASK);
        
public java.lang.StringgetDocumentStandalone(int nodeHandle)
Return an indication of the standalone status of the document, either "yes" or "no". This property is derived from the optional standalone document declaration in the XML declaration at the beginning of the document entity, and has no value if there is no standalone document declaration.

param
nodeHandle The node id, which can be any valid node handle.
return
the document standalone String object, either "yes", "no", or null.

return null;
public java.lang.StringgetDocumentSystemIdentifier(int nodeHandle)
Return the system identifier of the document entity. If it is not known, the value of this property is unknown.

param
nodeHandle The node id, which can be any valid node handle.
return
the system identifier String object or null if unknown.

return null;
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.

param
the document type declaration handle
return
the public identifier String object, or null if there is none.

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.

return null;
public java.lang.StringgetDocumentVersion(int documentHandle)
Return a string representing the XML version of the document. This property is derived from the XML declaration optionally present at the beginning of the document entity, and has no value if there is no XML declaration.

param
the document handle
return
the document version String object

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.

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

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


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

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


    return null;
  
public intgetExpandedTypeID(int nodeHandle)
Given a node handle, return an ID that represents the node's expanded name.

param
nodeHandle The handle to the node in question.
return
the expanded-name id of the node.

           nodes.readSlot(nodeHandle, gotslot);
           String qName = m_localNames.indexToString(gotslot[3]);
           // Remove prefix from qName
           // %TBD% jjk This is assuming the elementName is the qName.
           int colonpos = qName.indexOf(":");
           String localName = qName.substring(colonpos+1);
           // Get NS
           String namespace = m_nsNames.indexToString(gotslot[0] << 16);
           // Create expanded name
           String expandedName = namespace + ":" + localName;
           int expandedNameID = m_nsNames.stringToIndex(expandedName);

        return expandedNameID;
        
public intgetExpandedTypeID(java.lang.String namespace, java.lang.String localName, int type)
Given an expanded name, return an ID. If the expanded-name does not exist in the internal tables, the entry will be created, and the ID will be returned. Any additional nodes that are created that have this expanded name will use this ID.

param
nodeHandle The handle to the node in question.
return
the expanded-name id of the node.

           // Create expanded name
          // %TBD% jjk Expanded name is bitfield-encoded as
          // typeID[6]nsuriID[10]localID[16]. Switch to that form, and to
          // accessing the ns/local via their tables rather than confusing
          // nsnames and expandednames.
           String expandedName = namespace + ":" + localName;
           int expandedNameID = m_nsNames.stringToIndex(expandedName);

           return expandedNameID;
        
public intgetFirstAttribute(int nodeHandle)
Given a node handle, get the index of the node's first attribute.

param
nodeHandle int Handle of the Element node.
return
Handle of first attribute, or DTM.NULL to indicate none exists.

                nodeHandle &= NODEHANDLE_MASK;

                // %REVIEW% jjk: Just a quick observation: If you're going to
                // call readEntry repeatedly on the same node, it may be
                // more efficiently to do a readSlot to get the data locally,
                // reducing the addressing and call-and-return overhead.

                // Should we check if handle is element (do we want sanity checks?)
                if (ELEMENT_NODE != (nodes.readEntry(nodeHandle, 0) & 0xFFFF))
                        return NULL;
                // First Attribute (if any) should be at next position in table
                nodeHandle++;
                return(ATTRIBUTE_NODE == (nodes.readEntry(nodeHandle, 0) & 0xFFFF)) ?
                nodeHandle | m_docHandle : NULL;
        
public intgetFirstChild(int nodeHandle)
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.


                // ###shs worry about tracing/debug later
                nodeHandle &= NODEHANDLE_MASK;
                // Read node into variable
                nodes.readSlot(nodeHandle, gotslot);

                // type is the last half of first slot
                short type = (short) (gotslot[0] & 0xFFFF);

                // Check to see if Element or Document node
                if ((type == ELEMENT_NODE) || (type == DOCUMENT_NODE) ||
                                (type == ENTITY_REFERENCE_NODE)) {

                        // In case when Document root is given
                        //	if (nodeHandle == 0) nodeHandle = 1;
                        // %TBD% Probably was a mistake.
                        // If someone explicitly asks for first child
                        // of Document, I would expect them to want
                        // that and only that.

                        int kid = nodeHandle + 1;
                        nodes.readSlot(kid, gotslot);
                        while (ATTRIBUTE_NODE == (gotslot[0] & 0xFFFF)) {
                                // points to next sibling
                                kid = gotslot[2];
                                // Return NULL if node has only attributes
                                if (kid == NULL) return NULL;
                                nodes.readSlot(kid, gotslot);
                        }
                        // If parent slot matches given parent, return kid
                        if (gotslot[1] == nodeHandle)
                        {
                          int firstChild = kid | m_docHandle;

                          return firstChild;
                        }
                }
                // No child found

                return NULL;
        
public intgetFirstNamespaceNode(int nodeHandle, boolean inScope)
Given a node handle, get the index of the node's first child. If not yet resolved, waits for more nodes to be added to the document and tries again

param
nodeHandle handle to node, which should probably be an element node, but need not be.
param
inScope true if all namespaces in scope should be returned, false if only the namespace declarations should be returned.
return
handle of first namespace, or DTM.NULL to indicate none exists.


                return NULL;
        
public intgetLastChild(int nodeHandle)
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.

                // ###shs put trace/debug later
                nodeHandle &= NODEHANDLE_MASK;
                // do not need to test node type since getFirstChild does that
                int lastChild = NULL;
                for (int nextkid = getFirstChild(nodeHandle); nextkid != NULL;
                                nextkid = getNextSibling(nextkid)) {
                        lastChild = nextkid;
                }
                return lastChild | m_docHandle;
        
public shortgetLevel(int nodeHandle)
Get the depth level of this node in the tree (equals 1 for a parentless node).

param
nodeHandle The node id.
return
the number of ancestors, plus one
xsl.usage
internal

                short count = 0;
                while (nodeHandle != 0) {
                        count++;
                        nodeHandle = nodes.readEntry(nodeHandle, 1);
                }
                return count;
        
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...


    if (m_incrSAXSource instanceof IncrementalSAXSource_Filter)
      return (LexicalHandler) m_incrSAXSource;
    else
      return this;
  
public java.lang.StringgetLocalName(int nodeHandle)
Given a node handle, return its DOM-style localname. (As defined in Namespaces, this is the portion of the name after any colon character) %REVIEW% What's the local name of something other than Element/Attr? Should this be DOM-style (undefined unless namespaced), or other?

param
nodeHandle the id of the node.
return
String Local name of this node.

                nodes.readSlot(nodeHandle, gotslot);
                short type = (short) (gotslot[0] & 0xFFFF);
                String name = "";
                if ((type==ELEMENT_NODE) || (type==ATTRIBUTE_NODE)) {
                  int i=gotslot[3];
                  name=m_localNames.indexToString(i & 0xFFFF);
                  if(name==null) name="";
                }
                return name;
        
public java.lang.StringgetLocalNameFromExpandedNameID(int ExpandedNameID)
Given an expanded-name ID, return the local name part.

param
ExpandedNameID an ID that represents an expanded-name.
return
String Local name of this node.


           // Get expanded name
           String expandedName = m_localNames.indexToString(ExpandedNameID);
           // Remove prefix from expanded name
           int colonpos = expandedName.indexOf(":");
           String localName = expandedName.substring(colonpos+1);
           return localName;
        
public com.sun.org.apache.xml.internal.dtm.ref.DTMStringPoolgetLocalNameTable()
Get a reference pointer to the element name symbol table.

return
DTMStringPool reference to an instance of table.

                 return m_localNames;
         
public java.lang.StringgetNamespaceFromExpandedNameID(int ExpandedNameID)
Given an expanded-name ID, return the namespace URI part.

param
ExpandedNameID an ID that represents an expanded-name.
return
String URI value of this node's namespace, or null if no namespace was resolved.


           String expandedName = m_localNames.indexToString(ExpandedNameID);
           // Remove local name from expanded name
           int colonpos = expandedName.indexOf(":");
           String nsName = expandedName.substring(0, colonpos);

        return nsName;
        
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.)

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

return null;
public intgetNextAttribute(int nodeHandle)
Given a node handle, advance to the next attribute. If an element, we advance to its first attribute; if an attr, we advance to the next attr on the same node.

param
nodeHandle int Handle of the node.
return
int DTM node-number of the resolved attr, or DTM.NULL to indicate none exists.

                nodeHandle &= NODEHANDLE_MASK;
                nodes.readSlot(nodeHandle, gotslot);

                //%REVIEW% Why are we using short here? There's no storage
                //reduction for an automatic variable, especially one used
                //so briefly, and it typically costs more cycles to process
                //than an int would.
                short type = (short) (gotslot[0] & 0xFFFF);

                if (type == ELEMENT_NODE) {
                        return getFirstAttribute(nodeHandle);
                } else if (type == ATTRIBUTE_NODE) {
                        if (gotslot[2] != NULL)
                                return (m_docHandle | gotslot[2]);
                }
                return NULL;
        
public intgetNextDescendant(int subtreeRootHandle, int nodeHandle)
Given a node handle, advance to its next descendant. If not yet resolved, waits for more nodes to be added to the document and tries again.

param
subtreeRootNodeHandle
param
nodeHandle int Handle of the node.
return
handle of next descendant, or DTM.NULL to indicate none exists.

                subtreeRootHandle &= NODEHANDLE_MASK;
                nodeHandle &= NODEHANDLE_MASK;
                // Document root [Document Node? -- jjk] - no next-sib
                if (nodeHandle == 0)
                        return NULL;
                while (!m_isError) {
                        // Document done and node out of bounds
                        if (done && (nodeHandle > nodes.slotsUsed()))
                                break;
                        if (nodeHandle > subtreeRootHandle) {
                                nodes.readSlot(nodeHandle+1, gotslot);
                                if (gotslot[2] != 0) {
                                        short type = (short) (gotslot[0] & 0xFFFF);
                                        if (type == ATTRIBUTE_NODE) {
                                                nodeHandle +=2;
                                        } else {
                                                int nextParentPos = gotslot[1];
                                                if (nextParentPos >= subtreeRootHandle)
                                                        return (m_docHandle | (nodeHandle+1));
                                                else
                                                        break;
                                        }
                                } else if (!done) {
                                        // Add wait logic here
                                } else
                                        break;
                        } else {
                                nodeHandle++;
                        }
                }
                // Probably should throw error here like original instead of returning
                return NULL;
        
public intgetNextFollowing(int axisContextHandle, int nodeHandle)
Given a node handle, advance to the next node on the following axis.

param
axisContextHandle the start of the axis that is being traversed.
param
nodeHandle
return
handle of next sibling, or DTM.NULL to indicate none exists.

                //###shs still working on
                return NULL;
        
public intgetNextNamespaceNode(int baseHandle, int namespaceHandle, boolean inScope)
Given a namespace handle, advance to the next namespace. %TBD% THIS METHOD DOES NOT MATCH THE CURRENT SIGNATURE IN THE DTM INTERFACE. FIX IT, OR JUSTIFY CHANGING THE DTM API.

param
namespaceHandle handle to node which must be of type NAMESPACE_NODE.
return
handle of next namespace, or DTM.NULL to indicate none exists.

                // ###shs need to work on namespace
                return NULL;
        
public intgetNextPreceding(int axisContextHandle, int nodeHandle)
Given a node handle, advance to the next node on the preceding axis.

param
axisContextHandle the start of the axis that is being traversed.
param
nodeHandle the id of the node.
return
int Node-number of preceding sibling, or DTM.NULL to indicate none exists.

                // ###shs copied from Xalan 1, what is this suppose to do?
                nodeHandle &= NODEHANDLE_MASK;
                while (nodeHandle > 1) {
                        nodeHandle--;
                        if (ATTRIBUTE_NODE == (nodes.readEntry(nodeHandle, 0) & 0xFFFF))
                                continue;

                        // if nodeHandle is _not_ an ancestor of
                        // axisContextHandle, specialFind will return it.
                        // If it _is_ an ancestor, specialFind will return -1

                        // %REVIEW% unconditional return defeats the
                        // purpose of the while loop -- does this
                        // logic make any sense?

                        return (m_docHandle | nodes.specialFind(axisContextHandle, nodeHandle));
                }
                return NULL;
        
public intgetNextSibling(int nodeHandle)
Given a node handle, advance to its next sibling. %TBD% This currently uses the DTM-internal definition of sibling; eg, the last attr's next sib is the first child. In the old DTM, the DOM proxy layer provided the additional logic for the public view. If we're rewriting for XPath emulation, that test must be done here. %TBD% CODE INTERACTION WITH INCREMENTAL PARSE - If not yet resolved, should wait 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.

                nodeHandle &= NODEHANDLE_MASK;
                // Document root has no next sibling
                if (nodeHandle == 0)
                        return NULL;

                short type = (short) (nodes.readEntry(nodeHandle, 0) & 0xFFFF);
                if ((type == ELEMENT_NODE) || (type == ATTRIBUTE_NODE) ||
                                (type == ENTITY_REFERENCE_NODE)) {
                        int nextSib = nodes.readEntry(nodeHandle, 2);
                        if (nextSib == NULL)
                                return NULL;
                        if (nextSib != 0)
                                return (m_docHandle | nextSib);
                        // ###shs should cycle/wait if nextSib is 0? Working on threading next
                }
                // Next Sibling is in the next position if it shares the same parent
                int thisParent = nodes.readEntry(nodeHandle, 1);

                if (nodes.readEntry(++nodeHandle, 1) == thisParent)
                        return (m_docHandle | nodeHandle);

                return NULL;
        
public org.w3c.dom.NodegetNode(int nodeHandle)
Return an DOM node for the given node.

param
nodeHandle The node ID.
return
A node representation of the DTM node.

          return null;
        
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...

									// Notation

                                                             
            
                nodes.readSlot(nodeHandle, gotslot);
                short type = (short) (gotslot[0] & 0xFFFF);
                String name = fixednames[type];
                if (null == name) {
                  int i=gotslot[3];
                  /**/System.out.println("got i="+i+" "+(i>>16)+"/"+(i&0xffff));

                  name=m_localNames.indexToString(i & 0xFFFF);
                  String prefix=m_prefixNames.indexToString(i >>16);
                  if(prefix!=null && prefix.length()>0)
                    name=prefix+":"+name;
                }
                return name;
        
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.

return null;
public shortgetNodeType(int nodeHandle)
Given a node handle, return its DOM-style node type.

%REVIEW% Generally, returning short is false economy. Return int?

param
nodeHandle The node id.
return
int Node type, as per the DOM's Node._NODE constants.

                return(short) (nodes.readEntry(nodeHandle, 0) & 0xFFFF);
        
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.

                nodes.readSlot(nodeHandle, gotslot);
                int nodetype=gotslot[0] & 0xFF;		// ###zaj use mask to get node type
                String value=null;

                switch (nodetype) {			// ###zaj todo - document nodetypes
                case ATTRIBUTE_NODE:
                        nodes.readSlot(nodeHandle+1, gotslot);
                case TEXT_NODE:
                case COMMENT_NODE:
                case CDATA_SECTION_NODE:
                        value=m_char.getString(gotslot[2], gotslot[3]);		//###zaj
                        break;
                case PROCESSING_INSTRUCTION_NODE:
                case ELEMENT_NODE:
                case ENTITY_REFERENCE_NODE:
                default:
                        break;
                }
                return value;
        
public com.sun.org.apache.xml.internal.dtm.ref.DTMStringPoolgetNsNameTable()
Get a reference pointer to the namespace URI symbol table.

return
DTMStringPool reference to an instance of table.

                 return m_nsNames;
         
public intgetOwnerDocument(int nodeHandle)
Given a node handle, find the owning document node. This has the exact same semantics as the DOM Document method of the same name, in that if the nodeHandle is a document node, it will return NULL.

%REVIEW% Since this is DOM-specific, it may belong at the DOM binding layer. Included here as a convenience function and to aid porting of DOM code to DTM.

param
nodeHandle the id of the node.
return
int Node handle of owning document, or NULL if the nodeHandle is a document.

                // Assumption that Document Node is always in 0 slot
                if ((nodeHandle & NODEHANDLE_MASK) == 0)
                        return NULL;
                return (nodeHandle & DOCHANDLE_MASK);
        
public intgetParent(int nodeHandle)
Given a node handle, find its parent node.

param
nodeHandle the id of the node.
return
int Node-number of parent, or DTM.NULL to indicate none exists.

                // Should check to see within range?

                // Document Root should not have to be handled differently
                return (m_docHandle | nodes.readEntry(nodeHandle, 1));
        
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% Should this be DOM-style (undefined unless namespaced), or other?

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

                nodes.readSlot(nodeHandle, gotslot);
                short type = (short) (gotslot[0] & 0xFFFF);
                String name = "";
                if((type==ELEMENT_NODE) || (type==ATTRIBUTE_NODE)) {
                  int i=gotslot[3];
                  name=m_prefixNames.indexToString(i >>16);
                  if(name==null) name="";
                }
                return name;
        
public com.sun.org.apache.xml.internal.dtm.ref.DTMStringPoolgetPrefixNameTable()
Get a reference pointer to the prefix name symbol table.

return
DTMStringPool reference to an instance of table.

                return m_prefixNames;
        
public intgetPreviousSibling(int 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.

                nodeHandle &= NODEHANDLE_MASK;
                // Document root has no previous sibling
                if (nodeHandle == 0)
                        return NULL;

                int parent = nodes.readEntry(nodeHandle, 1);
                int kid = NULL;
                for (int nextkid = getFirstChild(parent); nextkid != nodeHandle;
                                nextkid = getNextSibling(nextkid)) {
                        kid = nextkid;
                }
                return kid | m_docHandle;
        
public javax.xml.transform.SourceLocatorgetSourceLocatorFor(int node)
Source information is not handled yet, so return null here.

param
node an int value
return
null

    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.

        // ###zaj - researching
        nodes.readSlot(nodeHandle, gotslot);
        int nodetype=gotslot[0] & 0xFF;
        String value=null;

        switch (nodetype) {
        case TEXT_NODE:
        case COMMENT_NODE:
        case CDATA_SECTION_NODE:
                value= m_char.getString(gotslot[2], gotslot[3]);
                break;
        case PROCESSING_INSTRUCTION_NODE:
        case ATTRIBUTE_NODE:
        case ELEMENT_NODE:
        case ENTITY_REFERENCE_NODE:
        default:
                break;
        }
        return m_xsf.newstr( value );

        
public char[]getStringValueChunk(int nodeHandle, int chunkIndex, int[] startAndLen)
Get a character array chunk in the string-value of a node. (see http://www.w3.org/TR/xpath#data-model for the definition of a node's string-value). Note that a single text node may have multiple text chunks. EXPLANATION: This method is an artifact of the fact that the underlying m_chars object may not store characters in a single contiguous array -- for example,the current FastStringBuffer may split a single node's text across multiple allocation units. This call retrieves a single contiguous portion of the text -- as much as m-chars was able to store in a single allocation unit. PLEASE NOTE that this may not be the same granularityas the SAX characters() events that caused the text node to be built in the first place, since m_chars buffering may be on different boundaries than the parser's buffers.

param
nodeHandle The node ID.
param
chunkIndex Which chunk to get.
param
startAndLen An array of 2 where the start position and length of the chunk will be returned.
return
The character array reference where the chunk occurs.

return new char[0];
public intgetStringValueChunkCount(int nodeHandle)
Get number of character array chunks in the string-value of a node. (see http://www.w3.org/TR/xpath#data-model for the definition of a node's string-value). Note that a single text node may have multiple text chunks. EXPLANATION: This method is an artifact of the fact that the underlying m_chars object may not store characters in a single contiguous array -- for example,the current FastStringBuffer may split a single node's text across multiple allocation units. This call tells us how many separate accesses will be required to retrieve the entire content. PLEASE NOTE that this may not be the same as the number of SAX characters() events that caused the text node to be built in the first place, since m_chars buffering may be on different boundaries than the parser's buffers.

param
nodeHandle The node ID.
return
number of character array chunks in the string-value of a node.

                //###zaj    return value
                return 0;
        
public com.sun.org.apache.xml.internal.dtm.DTMAxisIteratorgetTypedAxisIterator(int axis, int type)
Get an iterator that can navigate over an XPath Axis, predicated by the extended type ID.

param
axis
param
type An extended type ID.
return
A DTMAxisIterator, or null if the given axis isn't supported.

    // %TBD%
    return null;
  
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.

return null;
public booleanhasChildNodes(int nodeHandle)
Given a node handle, test if it has child nodes.

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

param
nodeHandle int Handle of the node.
return
int true if the given node has child nodes.

                return(getFirstChild(nodeHandle) != NULL);
        
public voidignorableWhitespace(char[] ch, int start, int length)

    // %TBD% I believe ignorable text isn't part of the DTM model...?
  
final voidinitDocument(int documentNumber)
Reset a dtm document to its initial (empty) state. The DTMManager will invoke this method when the dtm is created.

param
docHandle int the handle for the DTM document.

                // save masked DTM document handle
                m_docHandle = documentNumber<<DOCHANDLE_SHIFT;

                // Initialize the doc -- no parent, no next-sib
                nodes.writeSlot(0,DOCUMENT_NODE,-1,-1,0);
                // wait for the first startElement to create the doc root node
                done = false;
        
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
the attribute handle NEEDSDOC @param attributeHandle
return
true if the attribute was specified; false if it was defaulted.

return false;
public booleanisCharacterElementContentWhitespace(int nodeHandle)
2. [element content whitespace] A boolean indicating whether the character is white space appearing within element content (see [XML], 2.10 "White Space Handling"). Note that validating XML processors are required by XML 1.0 to provide this information. If there is no declaration for the containing element, this property has no value for white space characters. If no declaration has been read, but the [all declarations processed] property of the document information item is false (so there may be an unread declaration), then the value of this property is unknown for white space characters. It is always false for characters that are not white space.

param
nodeHandle the node ID.
return
true if the character data is whitespace; false otherwise.

return false;
public booleanisDocumentAllDeclarationsProcessed(int documentHandle)
10. [all declarations processed] This property is not strictly speaking part of the infoset of the document. Rather it is an indication of whether the processor has read the complete DTD. Its value is a boolean. If it is false, then certain properties (indicated in their descriptions below) may be unknown. If it is true, those properties are never unknown.

param
the document handle
param
documentHandle A node handle that must identify a document.
return
true if all declarations were processed; false otherwise.

return false;
public booleanisNodeAfter(int nodeHandle1, int nodeHandle2)
Figure out whether nodeHandle2 should be considered as being later in the document than nodeHandle1, in Document Order as defined by the XPath model. This may not agree with the ordering defined by other XML applications.

There are some cases where ordering isn't defined, and neither are the results of this function -- though we'll generally return true. TODO: Make sure this does the right thing with attribute nodes!!!

param
node1 DOM Node to perform position comparison on.
param
node2 DOM Node to perform position comparison on .
return
false if node2 comes before node1, otherwise return true. You can think of this as (node1.documentOrderPosition <= node2.documentOrderPosition).

return false;
public booleanisSupported(java.lang.String feature, java.lang.String version)
Tests whether DTM DOM implementation implements a specific feature and that feature is supported by this node.

param
feature The name of the feature to test.
param
versionThis is the version number of the feature to test. If the version is not specified, supporting any version of the feature will cause the method to return true.
return
Returns true if the specified feature is supported on this node, false otherwise.

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

   
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_incrSAXSource;
  
private voidprocessAccumulatedText()

    int len=m_char.length();
    if(len!=m_char_current_start)
      {
        // The FastStringBuffer has been previously agreed upon
        appendTextChild(m_char_current_start,len-m_char_current_start);
        m_char_current_start=len;
      }
  
public voidprocessingInstruction(java.lang.String target, java.lang.String data)

    processAccumulatedText();
    // %TBD% Which pools do target and data go into?
  
voidsetContentBuffer(com.sun.org.apache.xml.internal.utils.FastStringBuffer buffer)
Set a reference pointer to the content-text repository

param
bufferRef FastStringBuffer reference to an instance of buffer

                 m_char = buffer;
         
public voidsetDocumentBaseURI(java.lang.String baseURI)
Set the base URI of the document entity.

param
baseURI the document base URI String object or null if unknown.


          m_documentBaseURI = baseURI;
        
public voidsetDocumentLocator(org.xml.sax.Locator locator)

    // No-op for DTM
  
public voidsetFeature(java.lang.String featureId, boolean state)
Set an implementation dependent feature.

%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 voidsetIncrementalSAXSource(com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource source)
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
source The IncrementalSAXSource that we want to recieve events from on demand.

    m_incrSAXSource=source;

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

    // Are the following really needed? IncrementalSAXSource doesn't yet
    // support them, and they're mostly no-ops here...
    //source.setErrorHandler(this);
    //source.setDTDHandler(this);
    //source.setDeclHandler(this);
  
public voidsetLocalNameTable(com.sun.org.apache.xml.internal.dtm.ref.DTMStringPool poolRef)
Set a reference pointer to the element name symbol table. %REVIEW% Should this really be Public? Changing it while DTM is in use would be a disaster.

param
poolRef DTMStringPool reference to an instance of table.

                m_localNames = poolRef;
        
public voidsetNsNameTable(com.sun.org.apache.xml.internal.dtm.ref.DTMStringPool poolRef)
Set a reference pointer to the namespace URI symbol table. %REVIEW% Should this really be Public? Changing it while DTM is in use would be a disaster.

param
poolRef DTMStringPool reference to an instance of table.

                m_nsNames = poolRef;
        
public voidsetPrefixNameTable(com.sun.org.apache.xml.internal.dtm.ref.DTMStringPool poolRef)
Set a reference pointer to the prefix name symbol table. %REVIEW% Should this really be Public? Changing it while DTM is in use would be a disaster.

param
poolRef DTMStringPool reference to an instance of table.

                m_prefixNames = poolRef;
        
public voidsetProperty(java.lang.String property, java.lang.Object value)
For the moment all the run time properties are ignored by this class.

param
property a String value
param
value an Object value

  
public voidskippedEntity(java.lang.String name)

    processAccumulatedText();
    //%TBD%
  
public voidstartCDATA()

    // No-op in DTM
  
public voidstartDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)

    // No-op in DTM
  
public voidstartDocument()

    appendStartDocument();
  
public voidstartElement(java.lang.String namespaceURI, java.lang.String localName, java.lang.String qName, org.xml.sax.Attributes atts)

    processAccumulatedText();

    // %TBD% Split prefix off qname
    String prefix=null;
    int colon=qName.indexOf(':");
    if(colon>0)
      prefix=qName.substring(0,colon);

    // %TBD% Where do we pool expandedName, or is it just the union, or...
    /**/System.out.println("Prefix="+prefix+" index="+m_prefixNames.stringToIndex(prefix));
    appendStartElement(m_nsNames.stringToIndex(namespaceURI),
                     m_localNames.stringToIndex(localName),
                     m_prefixNames.stringToIndex(prefix)); /////// %TBD%

    // %TBD% I'm assuming that DTM will require resequencing of
    // NS decls before other attrs, hence two passes are taken.
    // %TBD% Is there an easier way to test for NSDecl?
    int nAtts=(atts==null) ? 0 : atts.getLength();
    // %TBD% Countdown is more efficient if nobody cares about sequence.
    for(int i=nAtts-1;i>=0;--i)
      {
        qName=atts.getQName(i);
        if(qName.startsWith("xmlns:") || "xmlns".equals(qName))
          {
            prefix=null;
            colon=qName.indexOf(':");
            if(colon>0)
              {
                prefix=qName.substring(0,colon);
              }
            else
              {
                // %REVEIW% Null or ""?
                prefix=null; // Default prefix
              }


            appendNSDeclaration(
                                    m_prefixNames.stringToIndex(prefix),
                                    m_nsNames.stringToIndex(atts.getValue(i)),
                                    atts.getType(i).equalsIgnoreCase("ID"));
          }
      }

    for(int i=nAtts-1;i>=0;--i)
      {
        qName=atts.getQName(i);
        if(!(qName.startsWith("xmlns:") || "xmlns".equals(qName)))
          {
            // %TBD% I hate having to extract the prefix into a new
            // string when we may never use it. Consider pooling whole
            // qNames, which are already strings?
            prefix=null;
            colon=qName.indexOf(':");
            if(colon>0)
              {
                prefix=qName.substring(0,colon);
                localName=qName.substring(colon+1);
              }
            else
              {
                prefix=""; // Default prefix
                localName=qName;
              }


            m_char.append(atts.getValue(i)); // Single-string value
            int contentEnd=m_char.length();

            if(!("xmlns".equals(prefix) || "xmlns".equals(qName)))
              appendAttribute(m_nsNames.stringToIndex(atts.getURI(i)),
                                  m_localNames.stringToIndex(localName),
                                  m_prefixNames.stringToIndex(prefix),
                                  atts.getType(i).equalsIgnoreCase("ID"),
                                  m_char_current_start, contentEnd-m_char_current_start);
            m_char_current_start=contentEnd;
          }
      }
  
public voidstartEntity(java.lang.String name)

    // No-op in DTM
  
public voidstartPrefixMapping(java.lang.String prefix, java.lang.String uri)

    // No-op in DTM, handled during element/attr processing?
  
public booleansupportsPreStripping()
Return true if the xsl:strip-space or xsl:preserve-space was processed during construction of the DTM document.

%REVEIW% Presumes a 1:1 mapping from DTM to Document, since we aren't saying which Document to query...?

return false;