sboag       99/12/12 23:46:59

  Modified:    src/org/apache/xalan/xpath/dtm DTM.java DTMLiaison.java
                        DTMNodeLocator.java DTMProxy.java
  Log:
  Primarily fixes for self::@foo patterns... added getFirstAttribute.  Also 
fixed problem with indexOf with qnames.
  
  Revision  Changes    Path
  1.5       +169 -67   xml-xalan/src/org/apache/xalan/xpath/dtm/DTM.java
  
  Index: DTM.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/dtm/DTM.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DTM.java  1999/11/27 08:53:23     1.4
  +++ DTM.java  1999/12/13 07:46:58     1.5
  @@ -70,8 +70,10 @@
   import org.apache.xerces.dom.ElementDefinitionImpl;
   import org.apache.xerces.dom.EntityImpl;
   import org.apache.xalan.xpath.xml.ProblemListener;
  +import org.apache.xalan.xpath.xml.StringToStringTable;
  +import org.apache.xalan.xpath.xml.StringVector;
  +import org.apache.xalan.xpath.xml.StringToStringTableVector;
   
  -
   /**
    * <code>DTM</code> is an XML document model expressed as a table rather than
    * an object tree. It attempts to be very compact, and to support very
  @@ -139,9 +141,6 @@
     // Impossible prefix to look up the default namespace
     public static final String DEFAULT_PREFIX_STR = "#:::";
   
  -  // Namespace lookup. This is actually a stack of hashtables
  -  Vector namespaceTable = new Vector(64);
  -
     // Handshaking for updates of simul read/write
     final int UPDATE_FREQUENCY=10;
     int update_counter=UPDATE_FREQUENCY;
  @@ -164,8 +163,16 @@
     IntToObjectMap m_elementDecls = new IntToObjectMap();
     
     IntMap m_idMap = new IntMap();
  +  
  +  /**
  +   * Namespace lookup. This is actually a stack of StringToStringTables
  +   */
  +  StringToStringTableVector namespaceTable = new 
StringToStringTableVector(64);
     
  -  private Hashtable m_emptyNamespace = new Hashtable();
  +  /**
  +   * Default empty namespace
  +   */
  +  private StringToStringTable m_emptyNamespace = new StringToStringTable();
     
     // This needs to be set before calling run()
     private InputSource m_inputSource = null;
  @@ -221,6 +228,8 @@
         fSchemaValidator = new NullSchemaValidator(fStringPool, 
fErrorReporter, fEntityHandler);
       return fSchemaValidator;
     }
  +  
  +  boolean m_throwNewError = true;
   
     
     /**
  @@ -230,17 +239,25 @@
     {
       try
       {
  +      m_throwNewError = true;
         parse(m_inputSource);
       }
  -    catch(Exception se)
  +    catch(Exception e)
       {
  +      e.printStackTrace();
         // Make sure nobody is still waiting
         synchronized (this)
         {
           m_isError = true;
           notifyAll();
  -        
  -        boolean shouldThrow = m_problemListener.message(se.getMessage());
  +        String msg = e.getMessage();
  +        if(null == msg)
  +        {
  +          // m_throwNewError = false;
  +          e.printStackTrace();
  +        }
  +        else
  +          m_problemListener.message(msg);
         }
         // Should I throw again??  In general, how should 
         // the error be handled from here.
  @@ -338,7 +355,8 @@
     public void appendAccumulatedText()
     {
       // No text pending
  -    if (charStartPos == charOffsets.slotsUsed())
  +    int slotsUsed = charOffsets.slotsUsed();
  +    if (charStartPos == slotsUsed)
         return;
       
       int nodetype = org.w3c.dom.Node.TEXT_NODE;
  @@ -351,7 +369,7 @@
   
       // Short Form, single block
       int w0, w1, w2, w3;
  -    if (charStartPos == charOffsets.slotsUsed()-1)
  +    if (charStartPos == slotsUsed-1)
       {
         charOffsets.readSlot(charStartPos+1, gotslot);
         // W0 Low: Node Type, with flag if ignorable whitespace
  @@ -506,21 +524,22 @@
       
       int colonpos = name.indexOf(':');
       String prefix = (colonpos <= 0) ? "" : name.substring(0, colonpos);
  -    String attrname, attrvalue;
   
       // Push a new namespace context
   
  -    Hashtable pushNS = m_emptyNamespace;
  +    StringToStringTable pushNS = m_emptyNamespace;
       // Process any new namespace declarations
       for (int i = 0; i < atts.getLength(); i++)
       {
  -      attrname = atts.getName(i);
  -      if (attrname.startsWith("xmlns:") || attrname.equals("xmlns"))
  +      String attrname = atts.getName(i);
  +      boolean isPrefix = attrname.startsWith("xmlns:");
  +      if (isPrefix || attrname.equals("xmlns")) 
         {
  -        attrvalue = atts.getValue(i);
  +        int index = attrname.indexOf(':');
  +        String p = isPrefix ? attrname.substring(index+1) : "";
           if(m_emptyNamespace == pushNS)
  -          pushNS = new Hashtable();
  -        pushNS.put(new 
Integer(stringToInt(attrname.substring(7))),attrvalue);
  +          pushNS = new StringToStringTable();
  +        pushNS.put(p, atts.getValue(i));
         }
       }
       namespaceTable.addElement(pushNS);
  @@ -545,10 +564,10 @@
       // Append the attributes
       for (int i = 0; i < atts.getLength(); i++)
       {
  -      attrname = atts.getName(i);
  +      String attrname = atts.getName(i);
         System.out.println(attrname);
         // ***** OBSOLETE, SHOULD PRODUCE SUBTREE!
  -      attrvalue = atts.getValue(i);
  +      String attrvalue = atts.getValue(i);
   
         // W0 Low: Node Type.
         // W0 High: Namespace
  @@ -597,13 +616,11 @@
       appendAccumulatedText();
       
       String name=intToString(elementNameIndex);
  -    int colonpos = name.indexOf(':');
  -    String prefix = (colonpos <= 0) ? "" : name.substring(0, colonpos);
       String attrname, attrvalue;
   
       // Push a new namespace context
   
  -    Hashtable pushNS=m_emptyNamespace;
  +    StringToStringTable pushNS=m_emptyNamespace;
       
       // Process any new namespace declarations
       if(attrListIndex!=-1)
  @@ -619,42 +636,49 @@
             attrvalue = fStringPool.toString(xmlAttrList.getAttValue(index));
             String nsprefix = attrname.substring(6);
             if(m_emptyNamespace == pushNS)
  -            pushNS = new Hashtable();
  +            pushNS = new StringToStringTable();
             pushNS.put(nsprefix,attrvalue);
           }
           else if(attrname.equals("xmlns"))
           {
             attrvalue = fStringPool.toString(xmlAttrList.getAttValue(index));
             if(m_emptyNamespace == pushNS)
  -            pushNS = new Hashtable();
  +            pushNS = new StringToStringTable();
             pushNS.put(DEFAULT_PREFIX_STR,attrvalue);
           }
         }
       }
       namespaceTable.addElement(pushNS);
       
  -    // This is ugly, but we have to be able to tell if a default namespace 
  -    // is in effect.
  -    if((prefix.length() == 0) && 
(resolveNamespace(DEFAULT_PREFIX_STR).length() > 0))
  +    // Scope some stuff...
  +    int ourslot;
       {
  -      prefix = DEFAULT_PREFIX_STR;
  -    }
  -
  -    // W0 Low: Node Type.
  -    // W0 High: Namespace
  -    int w0 = org.w3c.dom.Node.ELEMENT_NODE | 
(stringToInt(resolveNamespace(prefix)) << 16);
  -    // W1: Parent
  -    int w1 = currentParent;
  -    // W2: Next. Initialize as 0 (unresolved)
  -    int w2 = 0;
  -    // W3: Tagname
  -    int w3 = elementNameIndex;
  +      int colonpos = name.indexOf(':');
  +      String prefix = (colonpos <= 0) ? null : name.substring(0, colonpos);
  +      // This is ugly, but we have to be able to tell if a default namespace 
  +      // is in effect.
  +      if((null == prefix) && isDefaultNamespaceInEffect())
  +      {
  +        prefix = null;
  +      }
   
  -    // Add this element to the document
  -    int ourslot = appendNode(w0, w1, w2, w3);
  +      // W0 Low: Node Type.
  +      // W0 High: Namespace
  +      int w0 = org.w3c.dom.Node.ELEMENT_NODE | 
(stringToInt(resolveNamespace(prefix)) << 16);
  +      // W1: Parent
  +      int w1 = currentParent;
  +      // W2: Next. Initialize as 0 (unresolved)
  +      int w2 = 0;
  +      // W3: Tagname
  +      int w3 = elementNameIndex;
   
  +      // Add this element to the document
  +      ourslot = appendNode(w0, w1, w2, w3);
  +      
  +    }
       // Change append context
       currentParent = ourslot;
  +    
       previousSibling = 0;
       
       IntMap elemMap = (IntMap)m_elementDecls.get(elementNameIndex);
  @@ -685,10 +709,11 @@
             }
           }
   
  -        colonpos = attrname.indexOf(':');
  +        int w0;
  +        int colonpos = attrname.indexOf(':');
           if(colonpos > 0)
           {
  -          prefix = attrname.substring(0, colonpos);
  +          String prefix = attrname.substring(0, colonpos);
             w0 = org.w3c.dom.Node.ATTRIBUTE_NODE | 
(stringToInt(resolveNamespace(prefix)) << 16);
           }
           else
  @@ -696,11 +721,11 @@
             w0 = org.w3c.dom.Node.ATTRIBUTE_NODE;
           }
           // W1: Parent
  -        w1 = currentParent;
  +        int w1 = currentParent;
           // W2: Next (not yet resolved)
  -        w2 = 0;
  +        int w2 = 0;
           // W3: Tagname
  -        w3 = xmlAttrList.getAttrName(index);
  +        int w3 = xmlAttrList.getAttrName(index);
   
           // Add this element to the document
           ourslot = appendNode(w0, w1, w2, w3);
  @@ -775,7 +800,7 @@
       previousSiblingWasParent = true;
   
       // Pop a level of namespace table
  -    namespaceTable.removeElementAt(namespaceTable.size()-1);
  +    namespaceTable.removeLastElem();
     }
   
   
  @@ -1436,22 +1461,19 @@
     {
       if(TRACE)
         System.out.println("DTM: getFirstChild");
  -    
  -    // 0 is Document; first child is node 1.
  -    if (position == 0)
  -      return 1;
  -    
  +        
       // Examine the node in question  
       nodes.readSlot(position, gotslot);
   
       // If not an element or Attribute or EntRef, child is null
       int type = (gotslot[0] & 0xFFFF);
       if ((type != Node.ELEMENT_NODE) &&
  -        (type != Node.ATTRIBUTE_NODE) &&
  -        (type != Node.ENTITY_REFERENCE_NODE))
  +        (type != Node.ENTITY_REFERENCE_NODE) &&
  +        (type != Node.DOCUMENT_NODE))
         return -1;
       
  -    int parent = gotslot[1];
  +    // 0 is Document; first child is node 1.
  +    int parent = (position == 0) ? 1 : gotslot[1];
       
       // Advance to first non-Attr child
       // (First child of any kind is at position+1, thereafter walk sibs)
  @@ -1479,7 +1501,14 @@
       while (kid != -1)
       {
         nodes.readSlot(kid,gotslot);
  -      if((gotslot[1] == position) && ((gotslot[0]&0xff) != 
Node.ATTRIBUTE_NODE))
  +      boolean isAttr = ((gotslot[0]&0xff) == Node.ATTRIBUTE_NODE);
  +      if(isAttr)
  +      {
  +        // kid=getNextSibling(kid); // Since attrs have 2 nodes, advance by 2
  +        // if(kid == -1)
  +        //  break;
  +      }
  +      else if(gotslot[1] == position)
           return kid;
         else if(gotslot[1] == parent)
           break; // already to next sibling.
  @@ -1490,7 +1519,62 @@
       }
       return -1;
     }
  +  
  +  /**
  +   * DTM read API: Given a node index, 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 postition int Index of this node's record.
  +   * @return int DTM node-number of first child, or -1 to indicate none 
exists.
  +   */
  +  public int getFirstAttribute(int position)
  +  {
  +    if(TRACE)
  +      System.out.println("DTM: getFirstAttribute");
  +        
  +    // Examine the node in question  
  +    nodes.readSlot(position, gotslot);
  +
  +    // If not an element or Attribute or EntRef, child is null
  +    int type = (gotslot[0] & 0xFFFF);
  +    if (type != Node.ELEMENT_NODE)
  +      return -1;
  +    
  +    // 0 is Document; first child is node 1.
  +    int parent = (position == 0) ? 1 : gotslot[1];
  +    
  +    // Advance to first non-Attr child
  +    // (First child of any kind is at position+1, thereafter walk sibs)
  +    int kid=position+1;
  +    while((kid > nodes.lastUsed) && !done)
  +    {
  +      synchronized (this)
  +      {
  +        try
  +        {
  +          if(m_isError)
  +            break;
  +          if(DEBUG_WAITS)
  +            System.out.println("Waiting... getFirstChild");
  +          wait();
  +        }
  +        catch (InterruptedException e)
  +        {
  +          // That's OK, it's as good a time as any to check again
  +        }
  +      }
  +    }
  +
  +    nodes.readSlot(kid,gotslot);
  +    boolean isAttr = ((gotslot[0]&0xff) == Node.ATTRIBUTE_NODE);
  +    if(isAttr)
  +    {
  +      return kid;
  +    }
  +    return -1;
  +  }
   
  +
     /**
      * DTM read API: Given a node index, advance to the next attribute. If an
      * element, we advance to its first attribute; if an attr, we advance to
  @@ -1634,7 +1718,7 @@
         int type = nodes.readEntry(position, 0) & 0xFF;
         if (type == Node.ELEMENT_NODE ||
             type == Node.ATTRIBUTE_NODE ||
  -          type == Node.ENTITY_REFERENCE_NODE )
  +          type == Node.ENTITY_REFERENCE_NODE)
         { 
           int nextSib = nodes.readEntry(position, 2);
           if(nextSib != 0)
  @@ -1669,7 +1753,17 @@
           }
         }
       }
  -    throw new RuntimeException("Error occured!");
  +    // For now I'm going to be bad and try and recover...
  +    if(false)
  +    {
  +    if(m_throwNewError)
  +      throw new RuntimeException("Error occured!");
  +    }
  +    else
  +    {
  +      m_problemListener.message("Problem occured in DTM in getNextSibling... 
trying to recover");
  +    }
  +    return -1;
     }
     
     /**
  @@ -2213,17 +2307,25 @@
      */
     private String resolveNamespace(String prefix)
     {
  -    if(prefix==null || prefix=="")
  +    if(prefix==null || prefix.length() == 0)
         prefix=DEFAULT_PREFIX_STR;
  -    for(int i=namespaceTable.size()-1;i>=0;--i)
  -    {
  -      Hashtable locals=(Hashtable)namespaceTable.elementAt(i);
  -      String nsuri = (String) locals.get(prefix);
  -      if (nsuri != null)
  -        return nsuri;
  -    }
  -    return "";
  +    
  +    String nsuri = namespaceTable.get((prefix==null || prefix.length() == 0) 
? 
  +                                      DEFAULT_PREFIX_STR : prefix);
  +    return (null == nsuri) ? "" : nsuri;
  +  }
  +  
  +  /**
  +   * Internal routine: Look up a namespace in the current parent-element's
  +   * context, by consulting the stacked hashtables.
  +   * @param prefix String prefix to be resolved
  +   * @return String Namespace URI which that prefix currently points to.
  +   */
  +  private boolean isDefaultNamespaceInEffect()
  +  {
  +    return namespaceTable.containsKey(DEFAULT_PREFIX_STR);
     }
  +
   
     /**
      * This feature determines whether entity references within
  
  
  
  1.5       +2 -1      xml-xalan/src/org/apache/xalan/xpath/dtm/DTMLiaison.java
  
  Index: DTMLiaison.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/dtm/DTMLiaison.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DTMLiaison.java   1999/12/03 08:43:13     1.4
  +++ DTMLiaison.java   1999/12/13 07:46:58     1.5
  @@ -187,7 +187,8 @@
           m_document = parser.getDocument();
           if(null != source.getSystemId())
           {
  -          getSourceDocsTable().put(source.getSystemId(), m_document);
  +          if(null != getSourceDocsTable())
  +            getSourceDocsTable().put(source.getSystemId(), m_document);
           }
         }
       }
  
  
  
  1.5       +1 -1      
xml-xalan/src/org/apache/xalan/xpath/dtm/DTMNodeLocator.java
  
  Index: DTMNodeLocator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/dtm/DTMNodeLocator.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DTMNodeLocator.java       1999/11/28 04:25:12     1.4
  +++ DTMNodeLocator.java       1999/12/13 07:46:58     1.5
  @@ -264,7 +264,7 @@
         DTM dtm = dtmp.dtm;
         
         // Walk across the kids until all have been accounted for.
  -      for (int child = dtm.getNextAttribute(dtmpPos); 
  +      for (int child = dtm.getFirstAttribute(dtmpPos); 
              child != -1; 
              child = dtm.getNextAttribute(child))
         {
  
  
  
  1.3       +1 -1      xml-xalan/src/org/apache/xalan/xpath/dtm/DTMProxy.java
  
  Index: DTMProxy.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/dtm/DTMProxy.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DTMProxy.java     1999/11/23 04:06:02     1.2
  +++ DTMProxy.java     1999/12/13 07:46:58     1.3
  @@ -71,7 +71,7 @@
    * @see org.w3c.dom
    */
   public class DTMProxy
  -  implements Node, Document, Text, Element, Attr, ProcessingInstruction
  +  implements Node, Document, Text, Element, Attr, ProcessingInstruction, 
Comment
   {
     DTM dtm;
     int node;
  
  
  

Reply via email to