sboag       01/05/14 23:31:44

  Modified:    java/src/org/apache/xml/dtm Tag: DTM_EXP
                        CoroutineSAXParser.java DTMDefaultBase.java
                        DTMManagerDefault.java
               java/src/org/apache/xml/dtm/dom2dtm Tag: DTM_EXP
                        DOM2DTM.java
               java/src/org/apache/xml/dtm/sax2dtm Tag: DTM_EXP
                        SAX2DTM.java
  Log:
  Added very basic CoroutineSAXParser functionality to
  DTMManagerDefault, and debugged to the point where
  basic transforms seem to be working.  This involved once again
  reworking the character handling a bit in SAX2DTM.  Also, I had
  to pass the appID to the SAX2DTM class, rather than have it
  be created in the class.
  
  Right now when I run the test suite it has problems with some transforms.
  Note in particular attribvaltemplate01 and copy22.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.8   +70 -64    
xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineSAXParser.java
  
  Index: CoroutineSAXParser.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/CoroutineSAXParser.java,v
  retrieving revision 1.1.2.7
  retrieving revision 1.1.2.8
  diff -u -r1.1.2.7 -r1.1.2.8
  --- CoroutineSAXParser.java   2001/05/14 19:09:04     1.1.2.7
  +++ CoroutineSAXParser.java   2001/05/15 06:31:42     1.1.2.8
  @@ -504,7 +504,7 @@
                 try {
                 if(DEBUG)System.out.println("Inactive CoroutineSAXParser new 
parse "+arg);
                   xmlreader.parse((InputSource)arg);
  -             // Tell caller we returned from parsing
  +                // Tell caller we returned from parsing
                   arg=Boolean.FALSE;
                 }
   
  @@ -537,6 +537,12 @@
                   System.err.println(
                     "Inactive CoroutineSAXParser: unexpected resume parameter, 
"
                     +arg.getClass()+" with value=\""+arg+'"');
  +                  
  +                // If you don't do this, it can loop forever with the above
  +                // error printing out.  -sb
  +                arg = new RuntimeException(
  +                  "Inactive CoroutineSAXParser: unexpected resume parameter, 
"
  +                  +arg.getClass()+" with value=\""+arg+'"');
                 }
   
             } // end while
  @@ -590,18 +596,18 @@
     {
       try 
         {
  -     Object result=    
  -       fCoroutineManager.co_resume(source, appCoroutineID, 
fParserCoroutineID);
  -     
  -     // %REVIEW% Better error reporting needed... though most of these
  -     // should never arise during normal operation.
  -     // Should this rethrow the parse exception?
  -     if (result instanceof Exception) {
  -       System.out.println("\nParser threw exception:");
  -       ((Exception)result).printStackTrace();
  -     }
  +        Object result=    
  +          fCoroutineManager.co_resume(source, appCoroutineID, 
fParserCoroutineID);
  +        
  +        // %REVIEW% Better error reporting needed... though most of these
  +        // should never arise during normal operation.
  +        // Should this rethrow the parse exception?
  +        if (result instanceof Exception) {
  +          System.out.println("\nParser threw exception:");
  +          ((Exception)result).printStackTrace();
  +        }
   
  -     return result;
  +        return result;
         }
   
       // SHOULD NEVER OCCUR, since the coroutine number and coroutine manager
  @@ -609,7 +615,7 @@
       // So I'm just going to return it as a parsing exception, for now.
       catch(NoSuchMethodException e)
         {
  -     return e;
  +        return e;
         }
     }
     
  @@ -634,21 +640,21 @@
     {
       try 
         {
  -     Object result =
  -       fCoroutineManager.co_resume(parsemore?Boolean.TRUE:Boolean.FALSE,
  -                                   appCoroutineID, fParserCoroutineID);
  -     
  -     // %REVIEW% Better error reporting needed
  -     if (result == null)
  -       {
  -         System.out.println("\nUNEXPECTED: Parser doMore says shut down 
prematurely.\n");
  -       }
  -     else if (result instanceof Exception) {
  -       System.out.println("\nParser threw exception:");
  -       ((Exception)result).printStackTrace();
  -     }
  -     
  -     return result;
  +        Object result =
  +          fCoroutineManager.co_resume(parsemore?Boolean.TRUE:Boolean.FALSE,
  +                                      appCoroutineID, fParserCoroutineID);
  +        
  +        // %REVIEW% Better error reporting needed
  +        if (result == null)
  +          {
  +            System.out.println("\nUNEXPECTED: Parser doMore says shut down 
prematurely.\n");
  +          }
  +        else if (result instanceof Exception) {
  +          System.out.println("\nParser threw exception:");
  +          ((Exception)result).printStackTrace();
  +        }
  +        
  +        return result;
         }
     
       // SHOULD NEVER OCCUR, since the coroutine number and coroutine manager
  @@ -656,7 +662,7 @@
       // So I'm just going to return it as a parsing exception, for now.
       catch(NoSuchMethodException e)
         {
  -     return e;
  +        return e;
         }
     }
     
  @@ -678,15 +684,15 @@
       try
         {
           Object result =
  -       fCoroutineManager.co_resume(null, appCoroutineID, fParserCoroutineID);
  +          fCoroutineManager.co_resume(null, appCoroutineID, 
fParserCoroutineID);
   
  -     // Debugging; shouldn't arise in normal operation
  +        // Debugging; shouldn't arise in normal operation
           if(result!=null)
             System.out.println("\nUNEXPECTED: Parser doTerminate answers 
"+result);
         }
       catch(java.lang.NoSuchMethodException e)
         {
  -     // That's OK; if it doesn't exist, we don't need to terminate it
  +        // That's OK; if it doesn't exist, we don't need to terminate it
         }
     }
   
  @@ -721,41 +727,41 @@
       // Tell coroutine to begin parsing, run while parsing is in progress
       for(int arg=0;arg<args.length;++arg)
         {
  -     InputSource source = new InputSource(args[arg]);
  -     Object result=null;
  -     boolean more=true;
  -     /**    
  -       for(result = co.co_resume(source, appCoroutineID, parserCoroutineID);
  -       (result instanceof Boolean && ((Boolean)result)==Boolean.TRUE);
  -       result = co.co_resume(more, appCoroutineID, parserCoroutineID))
  -       **/
  -     for(result = parser.doParse(source, appCoroutineID);
  -         (result instanceof Boolean && ((Boolean)result)==Boolean.TRUE);
  -         result = parser.doMore(more, appCoroutineID))
  -       {
  -         System.out.println("\nSome parsing successful, trying more.\n");
  +        InputSource source = new InputSource(args[arg]);
  +        Object result=null;
  +        boolean more=true;
  +        /**    
  +          for(result = co.co_resume(source, appCoroutineID, 
parserCoroutineID);
  +          (result instanceof Boolean && ((Boolean)result)==Boolean.TRUE);
  +          result = co.co_resume(more, appCoroutineID, parserCoroutineID))
  +          **/
  +        for(result = parser.doParse(source, appCoroutineID);
  +            (result instanceof Boolean && ((Boolean)result)==Boolean.TRUE);
  +            result = parser.doMore(more, appCoroutineID))
  +          {
  +            System.out.println("\nSome parsing successful, trying more.\n");
               
  -         // Special test: Terminate parsing early.
  -         if(arg+1<args.length && "!".equals(args[arg+1]))
  -           {
  -             ++arg;
  -             more=false;
  -           }
  +            // Special test: Terminate parsing early.
  +            if(arg+1<args.length && "!".equals(args[arg+1]))
  +              {
  +                ++arg;
  +                more=false;
  +              }
               
  -       }
  +          }
  +        
  +        if (result instanceof Boolean && ((Boolean)result)==Boolean.FALSE)
  +          {
  +            System.out.println("\nParser ended (EOF or on request).\n");
  +          }
  +        else if (result == null) {
  +          System.out.println("\nUNEXPECTED: Parser says shut down 
prematurely.\n");
  +        }
  +        else if (result instanceof Exception) {
  +          System.out.println("\nParser threw exception:");
  +          ((Exception)result).printStackTrace();
  +        }
           
  -     if (result instanceof Boolean && ((Boolean)result)==Boolean.FALSE)
  -       {
  -         System.out.println("\nParser ended (EOF or on request).\n");
  -       }
  -     else if (result == null) {
  -       System.out.println("\nUNEXPECTED: Parser says shut down 
prematurely.\n");
  -     }
  -     else if (result instanceof Exception) {
  -       System.out.println("\nParser threw exception:");
  -       ((Exception)result).printStackTrace();
  -     }
  -     
         }
   
       parser.doTerminate(appCoroutineID);
  
  
  
  1.1.2.3   +242 -146  
xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDefaultBase.java
  
  Index: DTMDefaultBase.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDefaultBase.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- DTMDefaultBase.java       2001/05/14 20:52:16     1.1.2.2
  +++ DTMDefaultBase.java       2001/05/15 06:31:42     1.1.2.3
  @@ -75,12 +75,13 @@
   import javax.xml.transform.Source;
   
   /**
  - * The <code>DTMDefaultBase</code> class serves as a helper base for DTMs.  
  - * It sets up structures for navigation and type, while leaving data 
  + * The <code>DTMDefaultBase</code> class serves as a helper base for DTMs.
  + * It sets up structures for navigation and type, while leaving data
    * management and construction to the derived classes.
    */
   public abstract class DTMDefaultBase implements DTM
   {
  +
     /**
      * This is extra information about the node objects.  Each information
      * block is composed of several array members.  The size of this will 
always
  @@ -113,7 +114,7 @@
   
     /**
      * This represents the number of integers per node in the
  -   * <code>m_info</code> member variable, if the derived class 
  +   * <code>m_info</code> member variable, if the derived class
      * does not add information.
      */
     protected static final int DEFAULTNODEINFOBLOCKSIZE = 7;
  @@ -123,7 +124,7 @@
      */
     protected static final int NOTPROCESSED = DTM.NULL - 1;
   
  -  /** NEEDSDOC Field NODEIDENTITYBITS */
  +  /** Not sure if this is used? */
     protected static final int NODEIDENTITYBITS = 0x000FFFFF;
   
     /**
  @@ -139,16 +140,16 @@
   
     /** %TBD% Doc */
     protected String m_documentBaseURI;
  -  
  +
     /**
      * The whitespace filter that enables elements to strip whitespace or not.
      */
     protected DTMWSFilter m_wsfilter;
  -  
  -  /** Flag indicating whether to strip whitespace nodes          */
  +
  +  /** Flag indicating whether to strip whitespace nodes */
     protected boolean m_shouldStripWS = false;
   
  -  /** Stack of flags indicating whether to strip whitespace nodes          */
  +  /** Stack of flags indicating whether to strip whitespace nodes */
     protected BoolStack m_shouldStripWhitespaceStack;
   
     /**
  @@ -156,12 +157,13 @@
      *
      * @param mgr The DTMManager who owns this DTM.
      * @param domSource the DOM source that this DTM will wrap.
  +   * NEEDSDOC @param source
      * @param dtmIdentity The DTM identity ID for this DTM.
  -   * @param whiteSpaceFilter The white space filter for this DTM, which may 
  +   * @param whiteSpaceFilter The white space filter for this DTM, which may
      *                         be null.
      */
  -  public DTMDefaultBase(DTMManager mgr, Source source, 
  -                 int dtmIdentity, DTMWSFilter whiteSpaceFilter)
  +  public DTMDefaultBase(DTMManager mgr, Source source, int dtmIdentity,
  +                        DTMWSFilter whiteSpaceFilter)
     {
   
       m_mgr = mgr;
  @@ -169,9 +171,11 @@
       m_dtmIdent = dtmIdentity;
       m_mask = mgr.getNodeIdentityMask();
       m_wsfilter = whiteSpaceFilter;
  -    if(null != whiteSpaceFilter)
  +
  +    if (null != whiteSpaceFilter)
       {
         m_shouldStripWhitespaceStack = new BoolStack();
  +
         pushShouldStripWhitespace(false);
       }
     }
  @@ -184,23 +188,32 @@
      * @return identity+1, or DTM.NULL.
      */
     protected abstract int getNextNodeIdentity(int identity);
  -  
  +
     /**
      * 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 
  +   * @return The true if a next node is found or false if
      *         there are no more nodes.
      */
     protected abstract boolean nextNode();
  -  
  +
     /**
      * Return the number of integers in each node info block.
  +   *
  +   * NEEDSDOC ($objectName$) @return
      */
     protected int getNodeInfoBlockSize()
     {
       return DEFAULTNODEINFOBLOCKSIZE;
     }
  -  
  +
  +  /**
  +   * Get the number of nodes that have been added.
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   */
  +  protected abstract int getNumberOfNodes();
  +
     /**
      * Get a node handle that is relative to the given node.
      *
  @@ -212,28 +225,29 @@
     {
   
       int base = (identity * getNodeInfoBlockSize());
  -    // System.out.println("identity: "+identity+", base: "+
  -    //                     base+", blockSize: "+getNodeInfoBlockSize());
  -    int info = m_info.elementAt(base + offsetValue);
  +    int info = (identity >= getNumberOfNodes())
  +               ? NOTPROCESSED : m_info.elementAt(base + offsetValue);
   
       // Check to see if the information requested has been processed, and, 
       // if not, advance the iterator until we the information has been 
       // processed.
       while (info == NOTPROCESSED)
       {
  -      // System.out.println("NOT PROCESSED! getNodeInfo: 
"+getNodeName(identity)+" identity: "+identity);
         nextNode();
   
  -      info = m_info.elementAt(base + offsetValue);
  +      if (identity >= getNumberOfNodes())
  +        info = NOTPROCESSED;
  +      else
  +        info = m_info.elementAt(base + offsetValue);
       }
   
       return info;
     }
  -  
  +
     /**
  -   * Get a node handle that is relative to the given node, but don't check 
for 
  -   * the NOTPROCESSED flag.  A class will need to use this call to get 
values 
  -   * that may be negative.  Also, it's a tiny bit faster than getNodeInfo if 
  +   * Get a node handle that is relative to the given node, but don't check 
for
  +   * the NOTPROCESSED flag.  A class will need to use this call to get values
  +   * that may be negative.  Also, it's a tiny bit faster than getNodeInfo if
      * you know that NOTPROCESSED is not a possibility.
      *
      * @param identity The node identity.
  @@ -242,99 +256,137 @@
      */
     protected int getNodeInfoNoWait(int identity, int offsetValue)
     {
  -
  -    return m_info.elementAt((identity * getNodeInfoBlockSize()) + 
offsetValue);
  +    return m_info.elementAt((identity * getNodeInfoBlockSize())
  +                            + offsetValue);
     }
  -    
  +
     /**
      * Diagnostics function to dump the DTM.
      */
     public void dumpDTM()
     {
  -    while(nextNode()){}
  -    
  +
  +    while (nextNode()){}
  +
       int sizePerRecord = getNodeInfoBlockSize();
       int nRecords = m_info.size() / sizePerRecord;
  -    System.out.println("Total nodes: "+nRecords);
  -    
  -    for (int i = 0; i < nRecords; i++) 
  +
  +    System.out.println("Total nodes: " + nRecords);
  +
  +    for (int i = 0; i < nRecords; i++)
       {
  -      int offset = i*sizePerRecord;
  -      System.out.println("=========== "+i+" ===========");
  -      System.out.println("NodeName: "+getNodeName(i));
  -      System.out.println("NodeNameX: "+getNodeNameX(i));
  -      System.out.println("LocalName: "+getLocalName(i));
  -      System.out.println("NamespaceURI: "+getNamespaceURI(i));
  -      System.out.println("Prefix: "+getPrefix(i));
  -      
  +      int offset = i * sizePerRecord;
  +
  +      System.out.println("=========== " + i + " ===========");
  +      System.out.println("NodeName: " + getNodeName(i));
  +      System.out.println("NodeNameX: " + getNodeNameX(i));
  +      System.out.println("LocalName: " + getLocalName(i));
  +      System.out.println("NamespaceURI: " + getNamespaceURI(i));
  +      System.out.println("Prefix: " + getPrefix(i));
  +
         int exTypeID = getExpandedNameID(i);
  -      System.out.println("Expanded Type ID: "+Integer.toHexString(exTypeID));
  +
  +      System.out.println("Expanded Type ID: "
  +                         + Integer.toHexString(exTypeID));
   
         int type = getNodeType(i);
         String typestring;
  -      switch (type) 
  +
  +      switch (type)
         {
  -        case DTM.ATTRIBUTE_NODE: typestring = "ATTRIBUTE_NODE"; break;
  -        case DTM.CDATA_SECTION_NODE: typestring = "CDATA_SECTION_NODE"; 
break;
  -        case DTM.COMMENT_NODE: typestring = "COMMENT_NODE"; break;
  -        case DTM.DOCUMENT_FRAGMENT_NODE: typestring = 
"DOCUMENT_FRAGMENT_NODE"; break;
  -        case DTM.DOCUMENT_NODE: typestring = "DOCUMENT_NODE"; break;
  -        case DTM.DOCUMENT_TYPE_NODE: typestring = "DOCUMENT_NODE"; break;
  -        case DTM.ELEMENT_NODE: typestring = "ELEMENT_NODE"; break;
  -        case DTM.ENTITY_NODE: typestring = "ENTITY_NODE"; break;
  -        case DTM.ENTITY_REFERENCE_NODE: typestring = 
"ENTITY_REFERENCE_NODE"; break;
  -        case DTM.NAMESPACE_NODE: typestring = "NAMESPACE_NODE"; break;
  -        case DTM.NOTATION_NODE: typestring = "NOTATION_NODE"; break;
  -        case DTM.NULL: typestring = "NULL"; break;
  -        case DTM.PROCESSING_INSTRUCTION_NODE: typestring = 
"PROCESSING_INSTRUCTION_NODE"; break;
  -        case DTM.TEXT_NODE: typestring = "TEXT_NODE"; break;
  -        default: typestring = "Unknown!"; break;
  +      case DTM.ATTRIBUTE_NODE :
  +        typestring = "ATTRIBUTE_NODE";
  +        break;
  +      case DTM.CDATA_SECTION_NODE :
  +        typestring = "CDATA_SECTION_NODE";
  +        break;
  +      case DTM.COMMENT_NODE :
  +        typestring = "COMMENT_NODE";
  +        break;
  +      case DTM.DOCUMENT_FRAGMENT_NODE :
  +        typestring = "DOCUMENT_FRAGMENT_NODE";
  +        break;
  +      case DTM.DOCUMENT_NODE :
  +        typestring = "DOCUMENT_NODE";
  +        break;
  +      case DTM.DOCUMENT_TYPE_NODE :
  +        typestring = "DOCUMENT_NODE";
  +        break;
  +      case DTM.ELEMENT_NODE :
  +        typestring = "ELEMENT_NODE";
  +        break;
  +      case DTM.ENTITY_NODE :
  +        typestring = "ENTITY_NODE";
  +        break;
  +      case DTM.ENTITY_REFERENCE_NODE :
  +        typestring = "ENTITY_REFERENCE_NODE";
  +        break;
  +      case DTM.NAMESPACE_NODE :
  +        typestring = "NAMESPACE_NODE";
  +        break;
  +      case DTM.NOTATION_NODE :
  +        typestring = "NOTATION_NODE";
  +        break;
  +      case DTM.NULL :
  +        typestring = "NULL";
  +        break;
  +      case DTM.PROCESSING_INSTRUCTION_NODE :
  +        typestring = "PROCESSING_INSTRUCTION_NODE";
  +        break;
  +      case DTM.TEXT_NODE :
  +        typestring = "TEXT_NODE";
  +        break;
  +      default :
  +        typestring = "Unknown!";
  +        break;
         }
  -      System.out.println("Type: "+typestring);
  -      
  -      int firstChild = m_info.elementAt(offset+OFFSET_FIRSTCHILD);
  -      if(DTM.NULL == firstChild)
  +
  +      System.out.println("Type: " + typestring);
  +
  +      int firstChild = m_info.elementAt(offset + OFFSET_FIRSTCHILD);
  +
  +      if (DTM.NULL == firstChild)
           System.out.println("First child: DTM.NULL");
  -      else if(NOTPROCESSED == firstChild)
  +      else if (NOTPROCESSED == firstChild)
           System.out.println("First child: NOTPROCESSED");
         else
  -        System.out.println("First child: "+firstChild);
  -        
  -      int prevSibling = m_info.elementAt(offset+OFFSET_PREVSIBLING);
  -      if(DTM.NULL == prevSibling)
  +        System.out.println("First child: " + firstChild);
  +
  +      int prevSibling = m_info.elementAt(offset + OFFSET_PREVSIBLING);
  +
  +      if (DTM.NULL == prevSibling)
           System.out.println("Prev sibling: DTM.NULL");
  -      else if(NOTPROCESSED == prevSibling)
  +      else if (NOTPROCESSED == prevSibling)
           System.out.println("Prev sibling: NOTPROCESSED");
         else
  -        System.out.println("Prev sibling: "+prevSibling);
  +        System.out.println("Prev sibling: " + prevSibling);
   
  -      int nextSibling = m_info.elementAt(offset+OFFSET_NEXTSIBLING);
  -      if(DTM.NULL == nextSibling)
  +      int nextSibling = m_info.elementAt(offset + OFFSET_NEXTSIBLING);
  +
  +      if (DTM.NULL == nextSibling)
           System.out.println("Next sibling: DTM.NULL");
  -      else if(NOTPROCESSED == nextSibling)
  +      else if (NOTPROCESSED == nextSibling)
           System.out.println("Next sibling: NOTPROCESSED");
         else
  -        System.out.println("Next sibling: "+nextSibling);
  -        
  -      int parent = m_info.elementAt(offset+OFFSET_PARENT);
  -      if(DTM.NULL == parent)
  +        System.out.println("Next sibling: " + nextSibling);
  +
  +      int parent = m_info.elementAt(offset + OFFSET_PARENT);
  +
  +      if (DTM.NULL == parent)
           System.out.println("Parent: DTM.NULL");
  -      else if(NOTPROCESSED == parent)
  +      else if (NOTPROCESSED == parent)
           System.out.println("Parent: NOTPROCESSED");
         else
  -        System.out.println("Parent: "+parent);
  +        System.out.println("Parent: " + parent);
   
  -      int level = m_info.elementAt(offset+OFFSET_LEVEL);
  -      System.out.println("Level: "+level);
  +      int level = m_info.elementAt(offset + OFFSET_LEVEL);
   
  -      System.out.println("Node Value: "+getNodeValue(i));      
  -      System.out.println("String Value: "+getStringValue(i));      
  +      System.out.println("Level: " + level);
  +      System.out.println("Node Value: " + getNodeValue(i));
  +      System.out.println("String Value: " + getStringValue(i));
       }
  -    
     }
   
  -
  -
     // ========= DTM Implementation Control Functions. ==============
   
     /**
  @@ -425,7 +477,7 @@
      *   attribute.
      */
     public abstract int getAttributeNode(int nodeHandle, String namespaceURI,
  -                              String name);
  +                                       String name);
   
     /**
      * Given a node handle, get the index of the node's first attribute.
  @@ -446,6 +498,7 @@
   
         while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
         {
  +
           // Assume this can not be null.
           type = getNodeType(identity);
   
  @@ -534,67 +587,93 @@
   
       return DTM.NULL;
     }
  -  
  -  private Vector m_namespaceLists = null; // on demand
  -  
  +
  +  /** NEEDSDOC Field m_namespaceLists          */
  +  private Vector m_namespaceLists = null;  // on demand
  +
  +  /**
  +   * NEEDSDOC Method getNamespaceList 
  +   *
  +   *
  +   * NEEDSDOC @param baseHandle
  +   *
  +   * NEEDSDOC (getNamespaceList) @return
  +   */
     protected NodeVector getNamespaceList(int baseHandle)
     {
  -    if(null == m_namespaceLists)
  +
  +    if (null == m_namespaceLists)
         m_namespaceLists = new Vector();
       else
       {
         int n = m_namespaceLists.size();
  -      for (int i = (n-1); i >= 0; i--) 
  +
  +      for (int i = (n - 1); i >= 0; i--)
         {
  -        NodeVector ivec = (NodeVector)m_namespaceLists.elementAt(i);
  -        if(ivec.elementAt(0) == baseHandle)
  +        NodeVector ivec = (NodeVector) m_namespaceLists.elementAt(i);
  +
  +        if (ivec.elementAt(0) == baseHandle)
             return ivec;
         }
       }
  +
       NodeVector ivec = buildNamespaceList(baseHandle);
  +
       m_namespaceLists.addElement(ivec);
  +
       return ivec;
     }
  -  
  +
  +  /**
  +   * NEEDSDOC Method buildNamespaceList 
  +   *
  +   *
  +   * NEEDSDOC @param baseHandle
  +   *
  +   * NEEDSDOC (buildNamespaceList) @return
  +   */
     private NodeVector buildNamespaceList(int baseHandle)
     {
  +
       NodeVector ivec = new NodeVector(7);
  +
       ivec.addElement(-1);  // for base handle.
  -    
  +
       int nodeHandle = baseHandle;
       int type = getNodeType(baseHandle);
  -
       int namespaceHandle = DTM.NULL;
   
       if (DTM.ELEMENT_NODE == type)
       {
  +
         // We have to return in document order, so we actually want to find 
the 
         // first namespace decl of the last element that has a namespace decl.
  -
         // Assume that attributes and namespaces immediately follow the 
element.
         int identity = nodeHandle & m_mask;
  -      
  +
         while (DTM.NULL != identity)
         {
           identity = getNextNodeIdentity(identity);
  -        
           type = (DTM.NULL == identity) ? -1 : getNodeType(identity);
   
           if (type == DTM.NAMESPACE_NODE)
           {
             namespaceHandle = identity | m_dtmIdent;
  +
             ivec.insertInOrder(namespaceHandle);
           }
           else if (DTM.ATTRIBUTE_NODE != type)
           {
  -          if(identity > 0)
  +          if (identity > 0)
             {
               nodeHandle = getParent(nodeHandle);
  -            // System.out.println("parent: "+nodeHandle);
  -            if(nodeHandle == DTM.NULL)
  +
  +            if (nodeHandle == DTM.NULL)
                 break;
  +
               identity = nodeHandle & m_mask;
  -            if(identity == 0)
  +
  +            if (identity == 0)
                 break;
             }
             else
  @@ -602,11 +681,12 @@
           }
         }
       }
  +
       ivec.setElementAt(baseHandle, 0);
  +
       return ivec;
     }
   
  -  
     /**
      * 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
  @@ -627,23 +707,26 @@
   
       if (DTM.ELEMENT_NODE == type)
       {
  -      if(inScope)
  +      if (inScope)
         {
           NodeVector namespaces = getNamespaceList(nodeHandle);
           int n = namespaces.size();
  -        if(n > 1)
  +
  +        if (n > 1)
             return namespaces.elementAt(1);
         }
         else
         {
  +
           // Assume that attributes and namespaces immediately follow the 
element.
           int identity = nodeHandle & m_mask;
  -  
  +
           while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
           {
  +
             // Assume this can not be null.
             type = getNodeType(identity);
  -  
  +
             if (type == DTM.NAMESPACE_NODE)
             {
               return identity | m_dtmIdent;
  @@ -659,44 +742,49 @@
       return DTM.NULL;
     }
   
  -
     /**
      * Given a namespace handle, advance to the next namespace.
      *
  -   * @param baseHandle handle to original node from where the first 
namespace 
  +   * @param baseHandle handle to original node from where the first namespace
      * was relative to (needed to return nodes in document order).
      * @param namespaceHandle handle to node which must be of type
      * NAMESPACE_NODE.
  +   * NEEDSDOC @param nodeHandle
  +   * NEEDSDOC @param inScope
      * @return handle of next namespace, or DTM.NULL to indicate none exists.
      */
  -  public int getNextNamespaceNode(int baseHandle, int nodeHandle, boolean 
inScope)
  +  public int getNextNamespaceNode(int baseHandle, int nodeHandle,
  +                                  boolean inScope)
     {
  +
       int type = getNodeType(nodeHandle);
   
       if (DTM.NAMESPACE_NODE == type)
       {
  -      if(inScope)
  +      if (inScope)
         {
           NodeVector namespaces = getNamespaceList(baseHandle);
           int n = namespaces.size();
  -        for (int i = 1; i < n; i++) // start from 1 on purpose 
  +
  +        for (int i = 1; i < n; i++)  // start from 1 on purpose 
           {
  -          if(nodeHandle == namespaces.elementAt(i))
  +          if (nodeHandle == namespaces.elementAt(i))
             {
  -            if(i+1 < n)
  -              return namespaces.elementAt(i+1);
  +            if (i + 1 < n)
  +              return namespaces.elementAt(i + 1);
             }
           }
         }
         else
         {
  +
           // Assume that attributes and namespace nodes immediately follow the 
element.
           int identity = nodeHandle & m_mask;
  -  
  +
           while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
           {
             type = getNodeType(identity);
  -  
  +
             if (type == DTM.NAMESPACE_NODE)
             {
               return identity | m_dtmIdent;
  @@ -772,11 +860,11 @@
     {
   
       int identity = nodeHandle & m_mask;
  -    // System.out.println("identity: "+identity);
  -    if(identity > 0)
  +
  +    if (identity > 0)
       {
         int parent = getNodeInfo(identity, OFFSET_PARENT);
  -  
  +
         return parent | m_dtmIdent;
       }
       else
  @@ -831,7 +919,6 @@
      */
     public abstract String getStringValue(int nodeHandle);
   
  -
     /**
      * Get number of character array chunks in
      * the string-value of a node.
  @@ -849,6 +936,7 @@
   
       // %TBD%
       error("getStringValueChunkCount not yet supported!");
  +
       return 0;
     }
   
  @@ -871,6 +959,7 @@
   
       // %TBD%
       error("getStringValueChunk not yet supported!");
  +
       return null;
     }
   
  @@ -886,6 +975,7 @@
   
       int identity = nodeHandle & m_mask;
       int expandedNameID = getNodeInfo(identity, OFFSET_EXPANDEDNAMEID);
  +
       return expandedNameID;
     }
   
  @@ -896,6 +986,7 @@
      * expanded name will use this ID.
      *
      * @param nodeHandle The handle to the node in question.
  +   * NEEDSDOC @param type
      *
      * NEEDSDOC @param namespace
      * NEEDSDOC @param localName
  @@ -918,6 +1009,7 @@
      */
     public String getLocalNameFromExpandedNameID(int ExpandedNameID)
     {
  +
       ExpandedNameTable ent = m_mgr.getExpandedNameTable(this);
   
       return ent.getLocalName(ExpandedNameID);
  @@ -932,6 +1024,7 @@
      */
     public String getNamespaceFromExpandedNameID(int ExpandedNameID)
     {
  +
       ExpandedNameTable ent = m_mgr.getExpandedNameTable(this);
   
       return ent.getNamespace(ExpandedNameID);
  @@ -964,7 +1057,7 @@
   
       return null;
     }
  -  
  +
     /**
      * Given a node handle, return its XPath-style localname.
      * (As defined in Namespaces, this is the portion of the name after any
  @@ -1044,7 +1137,7 @@
       int identity = nodeHandle & m_mask;
   
       // Apparently, the axis walker stuff requires levels to count from 1.
  -    return (short) (getNodeInfo(identity, OFFSET_LEVEL)+1);
  +    return (short) (getNodeInfo(identity, OFFSET_LEVEL) + 1);
     }
   
     // ============== Document query functions ============== 
  @@ -1275,10 +1368,10 @@
     public boolean isNodeAfter(int nodeHandle1, int nodeHandle2)
     {
   
  -      int index1 = nodeHandle1 & m_mask;
  -      int index2 = nodeHandle2 & m_mask;
  +    int index1 = nodeHandle1 & m_mask;
  +    int index2 = nodeHandle2 & m_mask;
   
  -      return index1 <= index2;
  +    return index1 <= index2;
     }
   
     /**
  @@ -1320,7 +1413,6 @@
      */
     public boolean isDocumentAllDeclarationsProcessed(int documentHandle)
     {
  -
       return true;
     }
   
  @@ -1353,9 +1445,9 @@
      * @throws org.xml.sax.SAXException
      */
     public abstract void dispatchCharactersEvents(
  -          int nodeHandle, org.xml.sax.ContentHandler ch)
  -            throws org.xml.sax.SAXException;
  -  
  +    int nodeHandle, org.xml.sax.ContentHandler ch)
  +      throws org.xml.sax.SAXException;
  +
     /**
      * Directly create SAX parser events from a subtree.
      *
  @@ -1364,8 +1456,9 @@
      *
      * @throws org.xml.sax.SAXException
      */
  -  public abstract void dispatchToEvents(int nodeHandle, 
org.xml.sax.ContentHandler ch)
  -          throws org.xml.sax.SAXException;
  +  public abstract void dispatchToEvents(
  +    int nodeHandle, org.xml.sax.ContentHandler ch)
  +      throws org.xml.sax.SAXException;
   
     // ==== Construction methods (may not be supported by some 
implementations!) =====
   
  @@ -1399,17 +1492,19 @@
     {
       error("appendTextChild not yet supported!");
     }
  -  
  +
     /**
      * Simple error for asserts and the like.
  +   *
  +   * NEEDSDOC @param msg
      */
     protected void error(String msg)
     {
       throw new DTMException(msg);
     }
  -  
  -    /**
  -   * Find out whether or not to strip whispace nodes.  
  +
  +  /**
  +   * Find out whether or not to strip whispace nodes.
      *
      *
      * @return whether or not to strip whispace nodes.
  @@ -1420,7 +1515,7 @@
     }
   
     /**
  -   * Set whether to strip whitespaces and push in current value of   
  +   * Set whether to strip whitespaces and push in current value of
      * m_shouldStripWS in m_shouldStripWhitespaceStack.
      *
      * @param shouldStrip Flag indicating whether to strip whitespace nodes
  @@ -1430,33 +1525,34 @@
   
       m_shouldStripWS = shouldStrip;
   
  -    if(null != m_shouldStripWhitespaceStack)
  +    if (null != m_shouldStripWhitespaceStack)
         m_shouldStripWhitespaceStack.push(shouldStrip);
     }
   
     /**
  -   * Set whether to strip whitespaces at this point by popping out  
  -   * m_shouldStripWhitespaceStack. 
  +   * Set whether to strip whitespaces at this point by popping out
  +   * m_shouldStripWhitespaceStack.
      *
      */
     protected void popShouldStripWhitespace()
     {
  -    if(null != m_shouldStripWhitespaceStack)
  +    if (null != m_shouldStripWhitespaceStack)
         m_shouldStripWS = m_shouldStripWhitespaceStack.popAndTop();
     }
   
     /**
  -   * Set whether to strip whitespaces and set the top of the stack to 
  -   * the current value of m_shouldStripWS.  
  +   * Set whether to strip whitespaces and set the top of the stack to
  +   * the current value of m_shouldStripWS.
      *
      *
      * @param shouldStrip Flag indicating whether to strip whitespace nodes
      */
     protected void setShouldStripWhitespace(boolean shouldStrip)
     {
  -    
  +
       m_shouldStripWS = shouldStrip;
  -    if(null != m_shouldStripWhitespaceStack)
  +
  +    if (null != m_shouldStripWhitespaceStack)
         m_shouldStripWhitespaceStack.setTop(shouldStrip);
     }
   }
  
  
  
  1.1.2.7   +45 -26    
xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMManagerDefault.java
  
  Index: DTMManagerDefault.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMManagerDefault.java,v
  retrieving revision 1.1.2.6
  retrieving revision 1.1.2.7
  diff -u -r1.1.2.6 -r1.1.2.7
  --- DTMManagerDefault.java    2001/05/14 23:04:02     1.1.2.6
  +++ DTMManagerDefault.java    2001/05/15 06:31:42     1.1.2.7
  @@ -167,51 +167,70 @@
   
             xmlSource.setSystemId(urlOfSource);
           }
  -          
  -//        DTMDocumentImpl dtm = new DTMDocumentImpl(this, 
  -//                                                  documentID, 
  -//                                                  whiteSpaceFilter);
  -//
  -//        // It looks like you just construct this??
  -//        DTMBuilder builder = new DTMBuilder(dtm, xmlSource, reader);
   
  -        SAX2DTM dtm = new SAX2DTM(this, 
  -                                  source,
  -                                  documentID, 
  -                                  whiteSpaceFilter);
  -                                  
  -        reader.setContentHandler(dtm);
  -        reader.setDTDHandler(dtm);
  -        reader.setErrorHandler(dtm);
  -        
  -        try 
  -        {
  -          reader.setProperty("http://xml.org/sax/properties/lexical-handler";,
  -                                dtm);
  -        }
  -        catch (org.xml.sax.SAXException se) {}
           try
           {
             
reader.setFeature("http://apache.org/xml/features/validation/dynamic";,
                               true);
           }
           catch (org.xml.sax.SAXException se) {}
  -          
  +
  +        // Create the basic SAX2DTM.
  +        SAX2DTM dtm = new SAX2DTM(this, 
  +                                  source,
  +                                  documentID, 
  +                                  whiteSpaceFilter);
  +                                  
  +        // Go ahead and add the DTM to the lookup table.  This needs to be 
  +        // done before any parsing occurs.
           m_dtms.add(dtm);
           
  +        // Create a CoroutineManager to manage the coordination between the 
  +        // parser and the transformation.  This will "throttle" between 
  +        // the parser and the calling application.
  +        CoroutineManager coroutineManager=new CoroutineManager();
  +        
  +        // Create an CoRoutine ID for the transformation.
  +        int appCoroutine = coroutineManager.co_joinCoroutineSet(-1);
  +        // System.out.println("appCoroutine (mgr): "+appCoroutine);
  +        
  +        // %TBD% Test for a Xerces Parser, and create a 
  +        // CoroutineSAXParser_Xerces to avoid threading.
  +                                          
  +        // Create a CoroutineSAXParser that will run on the secondary thread.
  +        CoroutineSAXParser coParser=new CoroutineSAXParser(coroutineManager, 
appCoroutine, reader);
  +        
  +        // Have the DTM set itself up as the CoroutineSAXParser's listener.
  +        dtm.setCoroutineParser(coParser, appCoroutine);
  +        
  +        // Get the parser's CoRoutine ID.
  +        int parserCoroutine = coParser.getParserCoroutineID();
  +        // System.out.println("parserCoroutine (mgr): "+parserCoroutine);
  +    
  +        
  +        // %TBD%  It's probably OK to have these bypass the CoRoutine stuff??
  +        // Or maybe not?
  +        reader.setDTDHandler(dtm);
  +        reader.setErrorHandler(dtm);
  +                          
           try
           {
  -          reader.parse(xmlSource);
  +          // This is a strange way to start the parse.
  +          coParser.doParse(xmlSource, appCoroutine);
           }
           catch(RuntimeException re)
           {
  -          re.printStackTrace();
  +          coroutineManager.co_exit(appCoroutine);
             throw re;
           }
           catch(Exception e)
           {
  -          e.printStackTrace();
  +          coroutineManager.co_exit(appCoroutine);
             throw new org.apache.xml.utils.WrappedRuntimeException(e);
  +        }
  +        finally
  +        {
  +          // coroutineManager.co_exit(appCoroutine);
           }
   
           if(DUMPTREE)
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.12  +9 -0      
xml-xalan/java/src/org/apache/xml/dtm/dom2dtm/Attic/DOM2DTM.java
  
  Index: DOM2DTM.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/dom2dtm/Attic/DOM2DTM.java,v
  retrieving revision 1.1.2.11
  retrieving revision 1.1.2.12
  diff -u -r1.1.2.11 -r1.1.2.12
  --- DOM2DTM.java      2001/05/14 20:55:12     1.1.2.11
  +++ DOM2DTM.java      2001/05/15 06:31:43     1.1.2.12
  @@ -233,6 +233,15 @@
     {
       return NODEINFOBLOCKSIZE;
     }
  +  
  +  /**
  +   * Get the number of nodes that have been added.
  +   */
  +  protected int getNumberOfNodes()
  +  {
  +    return m_nodes.size();
  +  }
  +
   
     /**
      * This method iterates to the next node that will be added to the table.
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.7   +146 -98   
xml-xalan/java/src/org/apache/xml/dtm/sax2dtm/Attic/SAX2DTM.java
  
  Index: SAX2DTM.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/sax2dtm/Attic/SAX2DTM.java,v
  retrieving revision 1.1.2.6
  retrieving revision 1.1.2.7
  diff -u -r1.1.2.6 -r1.1.2.7
  --- SAX2DTM.java      2001/05/14 23:02:24     1.1.2.6
  +++ SAX2DTM.java      2001/05/15 06:31:44     1.1.2.7
  @@ -212,9 +212,11 @@
   
     /** Number of entries per record for m_entities. */
     private static final int ENTITY_FIELDS_PER = 4;
  -  
  -  /** Flag tells if text is pending that we need to 
  -   *  check for whitespace stripping. */
  +
  +  /**
  +   * Flag tells if text is pending that we need to
  +   *  check for whitespace stripping. 
  +   */
     private boolean m_textPending = false;
   
     /**
  @@ -250,6 +252,16 @@
     }
   
     /**
  +   * Get the CoRoutine ID for the application.
  +   *
  +   * @return The CoRoutine ID for the application.
  +   */
  +  public int getAppCoroutineID()
  +  {
  +    return m_appCoroutineID;
  +  }
  +
  +  /**
      * Bind a CoroutineParser 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.
  @@ -260,8 +272,10 @@
      *
      * @param coroutineParser The parser that we want to recieve events from
      * on demand.
  +   * @param appCoRID The CoRoutine ID for the application.
      */
  -  public void setCoroutineParser(CoroutineParser coroutineParser)
  +  public void setCoroutineParser(CoroutineParser coroutineParser,
  +                                 int appCoRID)
     {
   
       // Establish coroutine link so we can request more data
  @@ -275,8 +289,7 @@
   
       CoroutineManager cm = coroutineParser.getCoroutineManager();
   
  -    if (cm != null)
  -      m_appCoroutineID = cm.co_joinCoroutineSet(-1);
  +    m_appCoroutineID = appCoRID;
   
       // Establish SAX-stream link so we can receive the requested data
       coroutineParser.setContentHandler(this);
  @@ -539,38 +552,12 @@
   
       identity += 1;
   
  -    if (identity >= m_size)
  +    while (identity >= m_size)
       {
         if (m_coroutineParser == null)
  -        identity = DTM.NULL;
  -      else
  -        while (identity >= m_size)
  -        {
  -          Object gotMore = m_coroutineParser.doMore(true, m_appCoroutineID);
  +        return DTM.NULL;
   
  -          // gotMore may be a Boolean (TRUE if still parsing, FALSE if
  -          // EOF) or an exception if CoroutineParser 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))
  -          {
  -
  -            // %TBD% 
  -          }
  -
  -          if (gotMore != Boolean.TRUE & (identity >= m_size))
  -          {
  -
  -            // EOF reached without satisfying the request
  -            m_coroutineParser = null;  // Drop connection, stop trying
  -
  -            // %TBD% deregister as its listener?
  -            identity = DTM.NULL;  // Record not-found.
  -          }
  -        }
  +      nextNode();
       }
   
       return identity;
  @@ -619,6 +606,16 @@
     }
   
     /**
  +   * Get the number of nodes that have been added.
  +   *
  +   * @return The number of that are currently in the tree.
  +   */
  +  protected int getNumberOfNodes()
  +  {
  +    return m_size;
  +  }
  +
  +  /**
      * 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
  @@ -627,8 +624,41 @@
     protected boolean nextNode()
     {
   
  -    // %TODO% Add CoRoutine stuff.
  -    return false;
  +    if (null == m_coroutineParser)
  +      return false;
  +
  +    Object gotMore = m_coroutineParser.doMore(true, m_appCoroutineID);
  +
  +    // gotMore may be a Boolean (TRUE if still parsing, FALSE if
  +    // EOF) or an exception if CoroutineParser 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))
  +    {
  +
  +      // for now...
  +      m_coroutineParser.doTerminate(m_appCoroutineID);
  +      m_coroutineParser = null;
  +
  +      return false;
  +
  +      // %TBD% 
  +    }
  +
  +    if (gotMore != Boolean.TRUE)
  +    {
  +
  +      // EOF reached without satisfying the request
  +      m_coroutineParser.doTerminate(m_appCoroutineID);
  +      m_coroutineParser = null;  // Drop connection, stop trying
  +
  +      // %TBD% deregister as its listener?
  +    }
  +
  +    return true;
     }
   
     /**
  @@ -666,7 +696,6 @@
       int startInfo = nodeIndex * NODEINFOBLOCKSIZE;
   
       m_info.addElements(NODEINFOBLOCKSIZE);
  -
       m_info.setElementAt(level, startInfo + OFFSET_LEVEL);
       m_info.setElementAt(type, startInfo + OFFSET_TYPE);
       m_info.setElementAt((canHaveFirstChild) ? NOTPROCESSED : DTM.NULL,
  @@ -674,30 +703,35 @@
       m_info.setElementAt(NOTPROCESSED, startInfo + OFFSET_NEXTSIBLING);
       m_info.setElementAt(previousSibling, startInfo + OFFSET_PREVSIBLING);
       m_info.setElementAt(parentIndex, startInfo + OFFSET_PARENT);
  +    m_info.setElementAt(expandedTypeID, startInfo + OFFSET_EXPANDEDNAMEID);
  +    m_info.setElementAt(dataOrPrefix, startInfo + OFFSET_DATA_OR_QNAME);
   
  -    if (DTM.NULL != parentIndex && type != DTM.ATTRIBUTE_NODE
  -            && type != DTM.NAMESPACE_NODE)
  +    // Note that we don't want firstChild or nextSibling to be processed 
until
  +    // charactersFlush() is called.
  +    if (!m_textPending)
       {
  -      int startParentInfo = parentIndex * NODEINFOBLOCKSIZE;
  -
  -      if (NOTPROCESSED
  -              == m_info.elementAt(startParentInfo + OFFSET_FIRSTCHILD))
  +      if (DTM.NULL != parentIndex && type != DTM.ATTRIBUTE_NODE
  +              && type != DTM.NAMESPACE_NODE)
         {
  -        m_info.setElementAt(nodeIndex, startParentInfo + OFFSET_FIRSTCHILD);
  +        int startParentInfo = parentIndex * NODEINFOBLOCKSIZE;
  +
  +        if (NOTPROCESSED
  +                == m_info.elementAt(startParentInfo + OFFSET_FIRSTCHILD))
  +        {
  +          m_info.setElementAt(nodeIndex, startParentInfo + 
OFFSET_FIRSTCHILD);
  +        }
         }
  -    }
   
  -    m_info.setElementAt(expandedTypeID, startInfo + OFFSET_EXPANDEDNAMEID);
  +      // Note that we don't want nextSibling to be processed until
  +      // charactersFlush() is called.
  +      if (DTM.NULL != previousSibling)
  +      {
  +        int startPrevInfo = previousSibling * NODEINFOBLOCKSIZE;
   
  -    if (DTM.NULL != previousSibling)
  -    {
  -      m_info.setElementAt(nodeIndex,
  -                          (previousSibling * NODEINFOBLOCKSIZE)
  -                          + OFFSET_NEXTSIBLING);
  +        m_info.setElementAt(nodeIndex, startPrevInfo + OFFSET_NEXTSIBLING);
  +      }
       }
   
  -    m_info.setElementAt(dataOrPrefix, startInfo + OFFSET_DATA_OR_QNAME);
  -
       return nodeIndex;
     }
   
  @@ -1138,49 +1172,68 @@
     {
       m_idAttributes.put(id, new Integer(elem));
     }
  -  
  +
     /**
      * Check the last text node to see if it should be stripped.
      */
  -  protected void flushText()
  +  protected void charactersFlush()
     {
  +
       if (m_textPending)
       {
         m_textPending = false;
  -      if(!getShouldStripWhitespace())
  -        return;
  -        
  -      int lastNodeIdentity = m_size - 1;
  -
  -      int dataIndex = getNodeInfoNoWait(lastNodeIdentity,
  -                                        OFFSET_DATA_OR_QNAME);
  -                                        
  -      int offset = m_data.elementAt(dataIndex);
  -      int length = m_data.elementAt(dataIndex + 1);
  +
  +      boolean didStrip = false;
  +      int lastNodeIdentity = m_size;
  +
  +      if (getShouldStripWhitespace())
  +      {
  +        int dataIndex = getNodeInfoNoWait(lastNodeIdentity,
  +                                          OFFSET_DATA_OR_QNAME);
  +        int offset = m_data.elementAt(dataIndex);
  +        int length = m_data.elementAt(dataIndex + 1);
  +
  +        if (m_chars.isWhitespace(offset, length))
  +        {
  +          m_chars.setLength(m_chars.size() - length);
  +          m_info.setSize(m_info.size() - getNodeInfoBlockSize());
   
  -      if (m_chars.isWhitespace(offset, length))
  +          didStrip = true;
  +        }
  +      }
  +
  +      if (!didStrip)
         {
  -        m_chars.setLength(m_chars.size() - length);
  +        m_size++;
   
  -        // Go back and set the previous sibling to NULL for next.
  -        int prev = getNodeInfo(lastNodeIdentity, OFFSET_PREVSIBLING);
  +        int parentIndex = getNodeInfoNoWait(lastNodeIdentity, OFFSET_PARENT);
   
  +        if (DTM.NULL != parentIndex)
  +        {
  +          int startParentInfo = parentIndex * NODEINFOBLOCKSIZE;
  +
  +          if (NOTPROCESSED
  +                  == m_info.elementAt(startParentInfo + OFFSET_FIRSTCHILD))
  +          {
  +            m_info.setElementAt(lastNodeIdentity,
  +                                startParentInfo + OFFSET_FIRSTCHILD);
  +          }
  +        }
  +
  +        int prev = getNodeInfoNoWait(lastNodeIdentity, OFFSET_PREVSIBLING);
  +
           if (DTM.NULL != prev)
           {
  -          m_info.setElementAt(NOTPROCESSED,
  +          m_info.setElementAt(lastNodeIdentity,
                                 (prev * getNodeInfoBlockSize())
                                 + OFFSET_NEXTSIBLING);
  -          m_previous = prev;
           }
  -
  -        m_info.setSize(m_info.size() - getNodeInfoBlockSize());
   
  -        m_size--;
  +        m_previous = lastNodeIdentity;
         }
       }
     }
   
  -
     ////////////////////////////////////////////////////////////////////
     // Implementation of the EntityResolver interface.
     ////////////////////////////////////////////////////////////////////
  @@ -1342,8 +1395,8 @@
      */
     public void endDocument() throws SAXException
     {
  -    flushText();
   
  +    charactersFlush();
       m_info.setElementAt(DTM.NULL, OFFSET_NEXTSIBLING);
   
       int lastNode = m_previous;
  @@ -1360,8 +1413,7 @@
       m_contextIndexes = null;
   
       m_level--;
  -
  -    // dumpDTM();
  +    
     }
   
     /**
  @@ -1475,7 +1527,8 @@
             String uri, String localName, String qName, Attributes attributes)
               throws SAXException
     {
  -    flushText();
  +
  +    charactersFlush();
   
       int exName = m_ent.getExpandedNameID(uri, localName, DTM.ELEMENT_NODE);
       String prefix = getPrefix(qName, uri);
  @@ -1486,7 +1539,6 @@
   
       m_level++;
   
  -    // System.out.println("pushing: "+elemNode);     
       m_parents.push(elemNode);
   
       int startDecls = m_contextIndexes.peek();
  @@ -1526,8 +1578,6 @@
                 && (attrQName.equals("xmlns")
                     || attrQName.startsWith("xmlns:")))
         {
  -
  -        // System.out.println("prefix: "+prefix);
           if (declAlreadyDeclared(prefix))
             continue;  // go to the next attribute.
   
  @@ -1581,7 +1631,6 @@
   
       m_contextIndexes.push(m_prefixMappings.size());  // for the children.
     }
  -  
   
     /**
      * Receive notification of the end of an element.
  @@ -1609,7 +1658,8 @@
     public void endElement(String uri, String localName, String qName)
             throws SAXException
     {
  -    flushText();
  +
  +    charactersFlush();
   
       // If no one noticed, startPrefixMapping is a drag.
       // Pop the context for the last child (the one pushed by startElement)
  @@ -1625,7 +1675,6 @@
   
       m_previous = m_parents.pop();
   
  -    // System.out.println("pop of: "+m_previous);
       int startInfo = m_previous * NODEINFOBLOCKSIZE;
   
       if (m_info.elementAt(startInfo + OFFSET_FIRSTCHILD) == NOTPROCESSED)
  @@ -1637,8 +1686,6 @@
         startInfo = lastNode * NODEINFOBLOCKSIZE;
   
         m_info.setElementAt(DTM.NULL, startInfo + OFFSET_NEXTSIBLING);
  -
  -      // System.out.println("null nextSibling: "+getNodeName(lastNode));
       }
   
       popShouldStripWhitespace();
  @@ -1674,20 +1721,19 @@
       {
         int lastNodeIdentity = m_previous;
   
  -      dataIndex =
  -        getNodeInfoNoWait(lastNodeIdentity, OFFSET_DATA_OR_QNAME) + 1;
  +      dataIndex = getNodeInfoNoWait(lastNodeIdentity, OFFSET_DATA_OR_QNAME)
  +                  + 1;
   
  -      m_data.setElementAt(m_data.elementAt(dataIndex) + length,
  -                          dataIndex);
  +      m_data.setElementAt(m_data.elementAt(dataIndex) + length, dataIndex);
       }
       else
       {
  +      m_textPending = true;
   
  -      // System.out.println("Adding text node: prev ="+m_previous+", 
parent="+m_parents.peek());
  -      m_previous = addNode(m_textType, exName, m_level, m_parents.peek(),
  -                           m_previous, dataIndex, false);
  +      addNode(m_textType, exName, m_level, m_parents.peek(), m_previous,
  +              dataIndex, false);
   
  -      m_textPending = true;
  +      m_size--;  // doesn't really exist until charactersFlush.
       }
     }
   
  @@ -1734,8 +1780,9 @@
     public void processingInstruction(String target, String data)
             throws SAXException
     {
  -    flushText();
   
  +    charactersFlush();
  +
       int exName = m_ent.getExpandedNameID(null, target,
                                            DTM.PROCESSING_INSTRUCTION_NODE);
       int dataIndex = m_valuesOrPrefixes.stringToIndex(data);
  @@ -2047,7 +2094,8 @@
      */
     public void comment(char ch[], int start, int length) throws SAXException
     {
  -    flushText();
  +
  +    charactersFlush();
   
       int exName = m_ent.getExpandedNameID(DTM.COMMENT_NODE);
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to