minchau     2003/06/22 23:26:52

  Modified:    java/src/org/apache/xml/serializer ToSAXHandler.java
                        ToTextStream.java ToHTMLStream.java
                        ToXMLSAXHandler.java ToXMLStream.java
                        ToHTMLSAXHandler.java ToStream.java
                        SerializerBase.java
  Added:       java/src/org/apache/xml/serializer ElemContext.java
  Log:
  Moved a number of serializer instance variables into ElemContext,
  which is a stack to push/pop such values in unison. This makes
  the code clearer and less error prone and probably marginally
  (0.001%) faster.
  Submitted by: Brian Minchau
  
  Revision  Changes    Path
  1.4       +3 -3      
xml-xalan/java/src/org/apache/xml/serializer/ToSAXHandler.java
  
  Index: ToSAXHandler.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToSAXHandler.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ToSAXHandler.java 28 May 2003 15:11:14 -0000      1.3
  +++ ToSAXHandler.java 23 Jun 2003 06:26:51 -0000      1.4
  @@ -161,7 +161,7 @@
       {
   
           // Close any open element before emitting comment
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               closeStartTag();
           }
  @@ -290,10 +290,10 @@
                   m_needToCallStartDocument = false;
               }
   
  -            if (m_startTagOpen)
  +            if (m_elemContext.m_startTagOpen)
               {
                   closeStartTag();
  -                m_startTagOpen = false;
  +                m_elemContext.m_startTagOpen = false;
               }
               
               if (m_cdataTagOpen)
  
  
  
  1.7       +0 -7      
xml-xalan/java/src/org/apache/xml/serializer/ToTextStream.java
  
  Index: ToTextStream.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToTextStream.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ToTextStream.java 18 Jun 2003 14:59:45 -0000      1.6
  +++ ToTextStream.java 23 Jun 2003 06:26:51 -0000      1.7
  @@ -158,9 +158,6 @@
             String namespaceURI, String localName, String name, Attributes 
atts)
               throws org.xml.sax.SAXException
     {
  -
  -    m_currentElemDepth++;
  -
       // time to fire off startElement event
       if (m_tracer != null) {
           super.fireStartElem(name);
  @@ -198,7 +195,6 @@
     public void endElement(String namespaceURI, String localName, String name)
             throws org.xml.sax.SAXException
     {
  -        m_currentElemDepth--;
           if (m_tracer != null)
                    super.fireEndElem(name);           
     }
  @@ -567,7 +563,6 @@
        */
       public void endElement(String elemName) throws SAXException
       {
  -        m_currentElemDepth--;
                if (m_tracer != null)
               super.fireEndElem(elemName);                       
       }
  @@ -581,8 +576,6 @@
       String elementName) 
       throws SAXException 
       {
  -        m_currentElemDepth++;
  -
           if (m_needToCallStartDocument)
               startDocumentInternal();         
                // time to fire off startlement event.
  
  
  
  1.16      +51 -86    
xml-xalan/java/src/org/apache/xml/serializer/ToHTMLStream.java
  
  Index: ToHTMLStream.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToHTMLStream.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- ToHTMLStream.java 18 Jun 2003 14:59:45 -0000      1.15
  +++ ToHTMLStream.java 23 Jun 2003 06:26:51 -0000      1.16
  @@ -76,10 +76,6 @@
   
   public class ToHTMLStream extends ToStream 
   {
  -    /** State stack to keep track of if the current element has output 
  -     *  escaping disabled. 
  -     */
  -    protected final BoolStack m_isRawStack = new BoolStack();
   
       /** This flag is set while receiving events from the DTD */
       protected boolean m_inDTD = false;
  @@ -506,9 +502,6 @@
       /** True if the META tag should be omitted. */
       private boolean m_omitMetaTag = false;
   
  -    /** Element description of the element currently being processed */
  -    private ElemDesc m_elementDesc = null;
  -
       /**
        * Tells if the formatter should use special URL escaping.
        *
  @@ -719,10 +712,10 @@
       {
   
           // clean up any pending things first
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               closeStartTag();
  -            m_startTagOpen = false;
  +            m_elemContext.m_startTagOpen = false;
           }
           else if (m_cdataTagOpen)
           {
  @@ -756,7 +749,7 @@
                   if (m_ispreserve)
                       m_ispreserve = false;
                   else if (
  -                    (null != m_elementName)
  +                    (null != m_elemContext.m_elementName)
                       && (!m_inBlockElem
                           || isBlockElement) /* && !isWhiteSpaceSensitive */
                       )
  @@ -773,47 +766,37 @@
               if (atts != null)
                   addAttributes(atts);            
   
  -            // deal with the opening tag itself
  -            m_startTagOpen = true;
  -            m_elementDesc = elemDesc;
               m_isprevtext = false;
               final java.io.Writer writer = m_writer;
               writer.write('<');
               writer.write(name);
  -            
  -            
  -            // OPTIMIZE-EMPTY 
  -            if (elemDesc.is(ElemDesc.EMPTY))
  -            {
  -                // if the element is empty (has no children) then we can 
quit early and
  -                // not update all the other state information because the 
endElement() is
  -                // coming right away.  If you want to kill this optimization 
the corresponding
  -                // optimization "OPTIMIZE-EMPTY in endElement() must be 
killed too.
  -                if (m_tracer != null)
  -                    firePseudoAttributes();
   
  -                return;
  -            }
   
  -            // update any state information
  -            m_elementLocalName = localName;
  -            m_elementURI = namespaceURI;
  -            m_elementName = name;
  -            m_isRawStack.push(elemDesc.is(ElemDesc.RAW));
  -            m_currentElemDepth++; // current element is one element deeper
   
               if (m_tracer != null)
                   firePseudoAttributes();
  -
               
  +            if (elemDesc.is(ElemDesc.EMPTY) )  
  +            {
  +                // an optimization for elements which are expected
  +                // to be empty.  Only remember the element description.
  +                m_elemContext = m_elemContext.push();
  +                m_elemContext.m_elementDesc = elemDesc;
  +                return;                
  +            } 
  +            else
  +            {
  +                m_elemContext = 
m_elemContext.push(namespaceURI,localName,name);
  +                m_elemContext.m_elementDesc = elemDesc;
  +                m_elemContext.m_isRaw = elemDesc.is(ElemDesc.RAW);
  +            }
  +            
  +
               if (elemDesc.is(ElemDesc.HEADELEM))
               {
                   // This is the <HEAD> element, do some special processing
  -                if (m_startTagOpen)
  -                {
  -                    closeStartTag();
  -                    m_startTagOpen = false;
  -                }
  +                closeStartTag();
  +                m_elemContext.m_startTagOpen = false;
                   if (!m_omitMetaTag)
                   {
                       if (m_doIndent)
  @@ -864,14 +847,13 @@
           try
           {
   
  -            final ElemDesc elemDesc = getElemDesc(name);
  -            m_elementDesc = elemDesc;
  +            final ElemDesc elemDesc = m_elemContext.m_elementDesc;
               final boolean elemEmpty = elemDesc.is(ElemDesc.EMPTY);
   
               // deal with any indentation issues
               if (m_doIndent)
               {
  -                boolean isBlockElement = elemDesc.is(ElemDesc.BLOCK);
  +                final boolean isBlockElement = elemDesc.is(ElemDesc.BLOCK);
                   boolean shouldIndent = false;
   
                   if (m_ispreserve)
  @@ -883,13 +865,13 @@
                       m_startNewLine = true;
                       shouldIndent = true;
                   }
  -                if (!m_startTagOpen && shouldIndent)
  +                if (!m_elemContext.m_startTagOpen && shouldIndent)
                       indent();
                   m_inBlockElem = !isBlockElement;
               }
   
               final java.io.Writer writer = m_writer;
  -            if (!m_startTagOpen)
  +            if (!m_elemContext.m_startTagOpen)
               {
                   writer.write("</");
                   writer.write(name);
  @@ -897,10 +879,11 @@
               }
               else
               {
  -                // the start-tag was already closed.
  +                // the start-tag open when this method was called,
  +                // so we need to process it now.
                   
                   if (m_tracer != null)
  -                    super.fireStartElem(m_elementName);
  +                    super.fireStartElem(name);
   
                   // the starting tag was still open when we received this 
endElement() call
                   // so we need to process any gathered attributes NOW, before 
they go away.
  @@ -926,21 +909,12 @@
                   {
                       writer.write('>');
                   }
  -
  -                /* no need to call m_cdataSectionStates.pop();
  -                 * because pushCdataSectionState() was never called
  -                 * ... the endElement call came before we had a chance
  -                 * to push the state.
  -                 */
  -
               }
               
               // clean up because the element has ended
               if (elemDesc.is(ElemDesc.WHITESPACESENSITIVE))
                   m_ispreserve = true;
               m_isprevtext = false;
  -            m_elementURI = null;
  -            m_elementLocalName = null;
   
               // fire off the end element event
               if (m_tracer != null)
  @@ -952,27 +926,18 @@
                   // a quick exit if the HTML element had no children.
                   // This block of code can be removed if the corresponding 
block of code
                   // in startElement() also labeled with "OPTIMIZE-EMPTY" is 
also removed
  -                m_startTagOpen = false;
  +                m_elemContext = m_elemContext.m_prev;
                   return;
               }
   
               // some more clean because the element has ended. 
  -            if (!m_startTagOpen)
  +            if (!m_elemContext.m_startTagOpen)
               {
  -                if (m_cdataSectionElements != null)
  -                    m_cdataSectionStates.pop();
                   if (m_doIndent && !m_preserves.isEmpty())
                       m_preserves.pop();
               }
  -            else
  -                m_startTagOpen = false;
  -            /* At this point m_startTagOpen is always false because
  -             * we don't have any open tags anymore, since we just 
  -             * wrote out a closing ">" 
  -             */ 
  -
  -            m_currentElemDepth--;
  -            m_isRawStack.pop();
  +            m_elemContext = m_elemContext.m_prev;
  +//            m_isRawStack.pop();
           }
           catch (IOException e)
           {
  @@ -1439,14 +1404,14 @@
           throws org.xml.sax.SAXException
       {
   
  -        if (m_isRawStack.peekOrFalse())
  +        if (m_elemContext.m_isRaw)
           {
               try
               {
  -                if (m_startTagOpen)
  +                if (m_elemContext.m_startTagOpen)
                   {
                       closeStartTag();
  -                    m_startTagOpen = false;
  +                    m_elemContext.m_startTagOpen = false;
                   }
                   m_ispreserve = true;
                   
  @@ -1514,16 +1479,16 @@
           throws org.xml.sax.SAXException
       {
   
  -        if ((null != m_elementName)
  -            && (m_elementName.equalsIgnoreCase("SCRIPT")
  -                || m_elementName.equalsIgnoreCase("STYLE")))
  +        if ((null != m_elemContext.m_elementName)
  +            && (m_elemContext.m_elementName.equalsIgnoreCase("SCRIPT")
  +                || m_elemContext.m_elementName.equalsIgnoreCase("STYLE")))
           {
               try
               {
  -                if (m_startTagOpen)
  +                if (m_elemContext.m_startTagOpen)
                   {
                       closeStartTag();
  -                    m_startTagOpen = false;
  +                    m_elemContext.m_startTagOpen = false;
                   }
   
                   m_ispreserve = true;
  @@ -1582,10 +1547,10 @@
           {
               try
               {
  -            if (m_startTagOpen)
  +            if (m_elemContext.m_startTagOpen)
               {
                   closeStartTag();
  -                m_startTagOpen = false;
  +                m_elemContext.m_startTagOpen = false;
               }
               else if (m_needToCallStartDocument)
                   startDocumentInternal();
  @@ -1608,7 +1573,7 @@
               // Always output a newline char if not inside of an 
               // element. The whitespace is not significant in that
               // case.
  -            if (m_currentElemDepth <= 0)
  +            if (m_elemContext.m_currentElemDepth <= 0)
                   outputLineSep();
   
               m_startNewLine = true;
  @@ -1678,7 +1643,7 @@
                       writer,
                       m_attributes.getQName(i),
                       m_attributes.getValue(i),
  -                    m_elementDesc);
  +                    m_elemContext.m_elementDesc);
               }
       }
   
  @@ -1695,7 +1660,7 @@
   
               // finish processing attributes, time to fire off the start 
element event
               if (m_tracer != null)
  -                super.fireStartElem(m_elementName);  
  +                super.fireStartElem(m_elemContext.m_elementName);  
               
               int nAttrs = m_attributes.getLength();   
               if (nAttrs>0)
  @@ -1712,7 +1677,7 @@
                * section-elements list.
                */
               if (m_cdataSectionElements != null) 
  -                pushCdataSectionState();
  +                m_elemContext.m_isCdataSection = isCdataSection();
               if (m_doIndent)
               {
                   m_isprevtext = false;
  @@ -1788,16 +1753,16 @@
               throws SAXException
           {
               // hack for XSLTC with finding URI for default namespace
  -            if (m_elementURI == null)
  +            if (m_elemContext.m_elementURI == null)
               {
  -                String prefix1 = getPrefixPart(m_elementName);
  +                String prefix1 = getPrefixPart(m_elemContext.m_elementName);
                   if (prefix1 == null && EMPTYSTRING.equals(prefix))
                   {
                       // the elements URI is not known yet, and it
                       // doesn't have a prefix, and we are currently
                       // setting the uri for prefix "", so we have
                       // the uri for the element... lets remember it
  -                    m_elementURI = uri;
  +                    m_elemContext.m_elementURI = uri;
                   }
               }            
               startPrefixMapping(prefix,uri,false);
  @@ -1883,10 +1848,10 @@
       
       private void initToHTMLStream()
       {
  -        m_elementDesc = null;
  +//        m_elementDesc = null;
           m_inBlockElem = false;
           m_inDTD = false;
  -        m_isRawStack.clear();
  +//        m_isRawStack.clear();
           m_omitMetaTag = false;
           m_specialEscapeURLs = true;     
       }
  
  
  
  1.6       +16 -32    
xml-xalan/java/src/org/apache/xml/serializer/ToXMLSAXHandler.java
  
  Index: ToXMLSAXHandler.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToXMLSAXHandler.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ToXMLSAXHandler.java      28 May 2003 15:11:14 -0000      1.5
  +++ ToXMLSAXHandler.java      23 Jun 2003 06:26:52 -0000      1.6
  @@ -232,26 +232,23 @@
       protected void closeStartTag() throws SAXException
       {
   
  -        m_startTagOpen = false;
  +        m_elemContext.m_startTagOpen = false;
   
  -        final String localName = getLocalName(m_elementName);
  -        final String uri = getNamespaceURI(m_elementName, true);
  +        final String localName = getLocalName(m_elemContext.m_elementName);
  +        final String uri = getNamespaceURI(m_elemContext.m_elementName, 
true);
   
           // Now is time to send the startElement event
           if (m_needToCallStartDocument)
           {
               startDocumentInternal();
           }
  -        m_saxHandler.startElement(uri, localName, m_elementName, 
m_attributes);
  +        m_saxHandler.startElement(uri, localName, 
m_elemContext.m_elementName, m_attributes);
           // we've sent the official SAX attributes on their way,
           // now we don't need them anymore.
           m_attributes.clear();
   
           if(m_state != null)
             m_state.setCurrentNode(null);
  -
  -        pushCdataSectionState();
  -
       }
   
       /**
  @@ -276,16 +273,16 @@
           
           if (namespaceURI == null)
           {
  -            if (m_elementURI != null)
  -                namespaceURI = m_elementURI;
  +            if (m_elemContext.m_elementURI != null)
  +                namespaceURI = m_elemContext.m_elementURI;
               else
                   namespaceURI = getNamespaceURI(qName, true);
           }
           
           if (localName == null)
           {
  -            if (m_elementLocalName != null)
  -                localName = m_elementLocalName;
  +            if (m_elemContext.m_elementLocalName != null)
  +                localName = m_elemContext.m_elementLocalName;
               else
                   localName = getLocalName(qName);
           }
  @@ -298,14 +295,8 @@
           /* Pop all namespaces at the current element depth.
            * We are not waiting for official endPrefixMapping() calls.
            */
  -        m_prefixMap.popNamespaces(m_currentElemDepth);
  -        m_currentElemDepth--;
  -        m_startTagOpen = false;
  -        // m_disableOutputEscapingStates.pop();
  -        if (m_cdataSectionElements != null)
  -            m_cdataSectionStates.pop();
  -        m_elementURI = null;
  -        m_elementLocalName = null;
  +        m_prefixMap.popNamespaces(m_elemContext.m_currentElemDepth);
  +        m_elemContext = m_elemContext.m_prev;
       }
   
       /**
  @@ -384,12 +375,12 @@
           {
               flushPending();
               // the prefix mapping applies to the child element (one deeper)
  -            pushDepth = m_currentElemDepth + 1;
  +            pushDepth = m_elemContext.m_currentElemDepth + 1;
           }
           else
           {
               // the prefix mapping applies to the current element
  -            pushDepth = m_currentElemDepth;
  +            pushDepth = m_elemContext.m_currentElemDepth;
           }
           pushed = m_prefixMap.pushNamespace(prefix, uri, pushDepth);
   
  @@ -522,7 +513,7 @@
   
           flushPending();
   
  -        if (m_cdataSectionStates.peekOrFalse())
  +        if (m_elemContext.m_isCdataSection)
           {
               startCDATA(ch, off, len);
           }
  @@ -667,27 +658,20 @@
                }
                m_needToOutputDocTypeDecl = false;
            }
  -
  -        m_currentElemDepth++; // current element is one element deeper
  +        m_elemContext = m_elemContext.push(namespaceURI, localName, name);
   
           // ensurePrefixIsDeclared depends on the current depth, so
           // the previous increment is necessary where it is.
           if (namespaceURI != null)
               ensurePrefixIsDeclared(namespaceURI, name);
   
  -        // remember for later
  -        m_elementLocalName = localName;  // null if not known yet
  -        m_elementURI = namespaceURI;     // null if not known yet
  -        m_elementName = name;            // required 
  -
           // add the attributes to the collected ones
           if (atts != null)
               addAttributes(atts);
   
  -        m_startTagOpen = true;
            
           // do we really need this CDATA section state?
  -        pushCdataSectionState();
  +        m_elemContext.m_isCdataSection = isCdataSection();
      
       }
    
  @@ -744,7 +728,7 @@
           String value)
           throws SAXException
       {      
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               ensurePrefixIsDeclared(uri, rawName);
               addAttributeAlways(uri, localName, rawName, type, value);
  
  
  
  1.6       +11 -15    
xml-xalan/java/src/org/apache/xml/serializer/ToXMLStream.java
  
  Index: ToXMLStream.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToXMLStream.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ToXMLStream.java  9 Jun 2003 21:50:56 -0000       1.5
  +++ ToXMLStream.java  23 Jun 2003 06:26:52 -0000      1.6
  @@ -118,15 +118,10 @@
   
           setOmitXMLDeclaration(xmlListener.getOmitXMLDeclaration());
   
  -        m_startTagOpen = xmlListener.m_startTagOpen;
  -
  -        // m_lineSep = xmlListener.m_lineSep;
  -        // m_lineSepLen = xmlListener.m_lineSepLen;
           m_ispreserve = xmlListener.m_ispreserve;
           m_preserves = xmlListener.m_preserves;
           m_isprevtext = xmlListener.m_isprevtext;
           m_doIndent = xmlListener.m_doIndent;
  -        m_currentElemDepth = xmlListener.m_currentElemDepth;
           setIndentAmount(xmlListener.getIndentAmount());
           m_startNewLine = xmlListener.m_startNewLine;
           m_needToOutputDocTypeDecl = xmlListener.m_needToOutputDocTypeDecl;
  @@ -295,10 +290,10 @@
           {
               try
               {
  -                if (m_startTagOpen)
  +                if (m_elemContext.m_startTagOpen)
                   {
                       closeStartTag();
  -                    m_startTagOpen = false;
  +                    m_elemContext.m_startTagOpen = false;
                   }
   
                   if (shouldIndent())
  @@ -341,7 +336,7 @@
                   // Always output a newline char if not inside of an
                   // element. The whitespace is not significant in that
                   // case.
  -                if (m_currentElemDepth <= 0)
  +                if (m_elemContext.m_currentElemDepth <= 0)
                       writer.write(m_lineSep, 0, m_lineSepLen);
   
                   m_startNewLine = true;
  @@ -365,10 +360,10 @@
        */
       public void entityReference(String name) throws org.xml.sax.SAXException
       {
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               closeStartTag();
  -            m_startTagOpen = false;
  +            m_elemContext.m_startTagOpen = false;
           }
   
           try
  @@ -399,7 +394,7 @@
           String value)
           throws SAXException
       {
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               if (!rawName.startsWith("xmlns"))
               {
  @@ -519,16 +514,16 @@
       {
   
           // hack for XSLTC with finding URI for default namespace
  -        if (m_elementURI == null)
  +        if (m_elemContext.m_elementURI == null)
           {
  -            String prefix1 = getPrefixPart(m_elementName);
  +            String prefix1 = getPrefixPart(m_elemContext.m_elementName);
               if (prefix1 == null && EMPTYSTRING.equals(prefix))
               {
                   // the elements URI is not known yet, and it
                   // doesn't have a prefix, and we are currently
                   // setting the uri for prefix "", so we have
                   // the uri for the element... lets remember it
  -                m_elementURI = uri;
  +                m_elemContext.m_elementURI = uri;
               }
           }            
           startPrefixMapping(prefix,uri,false);
  @@ -545,7 +540,8 @@
       {
           try
           {
  -            if (m_prefixMap.pushNamespace(prefix, uri, m_currentElemDepth))
  +            if (m_prefixMap.pushNamespace(
  +                prefix, uri, m_elemContext.m_currentElemDepth))
               {
                   startPrefixMapping(prefix, uri);
                   return true;
  
  
  
  1.4       +10 -17    
xml-xalan/java/src/org/apache/xml/serializer/ToHTMLSAXHandler.java
  
  Index: ToHTMLSAXHandler.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToHTMLSAXHandler.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ToHTMLSAXHandler.java     28 May 2003 15:54:34 -0000      1.3
  +++ ToHTMLSAXHandler.java     23 Jun 2003 06:26:52 -0000      1.4
  @@ -381,7 +381,7 @@
           flushPending();
           super.startElement(namespaceURI, localName, qName, atts);
           m_saxHandler.startElement(namespaceURI, localName, qName, atts);
  -        m_startTagOpen = false;
  +        m_elemContext.m_startTagOpen = false;
       }
   
       /**
  @@ -472,13 +472,13 @@
       protected void closeStartTag() throws SAXException
       {
   
  -        m_startTagOpen = false;
  +        m_elemContext.m_startTagOpen = false;
   
           // Now is time to send the startElement event
           m_saxHandler.startElement(
               EMPTYSTRING,
  -            m_elementName,
  -            m_elementName,
  +            m_elemContext.m_elementName,
  +            m_elemContext.m_elementName,
               m_attributes);
           m_attributes.clear();       
   
  @@ -565,14 +565,7 @@
                       doctypeSystem);
               m_lexHandler = null;
           }
  -
  -        m_currentElemDepth++;
  -        m_elementName = elementName;         // required
  -        m_elementLocalName = elementLocalName; // possibly null (optional)
  -        m_elementURI = elementNamespaceURI;  // possibly null (optional)
  -//        m_attributes.clear();
  -        m_startTagOpen = true;
  -
  +        m_elemContext = m_elemContext.push(elementNamespaceURI, 
elementLocalName, elementName);
       }
       /**
        * An element starts, but attributes are not fully known yet.
  @@ -657,7 +650,7 @@
                        } catch (SAXException e) {}
                }               
           // Close any open element
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               try
               {
  @@ -667,7 +660,7 @@
               {
                   // do something ??
               }
  -            m_startTagOpen = false;
  +            m_elemContext.m_startTagOpen = false;
           }
       }
       /**
  @@ -740,16 +733,16 @@
           throws SAXException
       {
           // hack for XSLTC with finding URI for default namespace
  -        if (m_elementURI == null)
  +        if (m_elemContext.m_elementURI == null)
           {
  -            String prefix1 = getPrefixPart(m_elementName);
  +            String prefix1 = getPrefixPart(m_elemContext.m_elementName);
               if (prefix1 == null && EMPTYSTRING.equals(prefix))
               {
                   // the elements URI is not known yet, and it
                   // doesn't have a prefix, and we are currently
                   // setting the uri for prefix "", so we have
                   // the uri for the element... lets remember it
  -                m_elementURI = uri;
  +                m_elemContext.m_elementURI = uri;
               }
           }       
           startPrefixMapping(prefix,uri,false);
  
  
  
  1.14      +31 -48    
xml-xalan/java/src/org/apache/xml/serializer/ToStream.java
  
  Index: ToStream.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/serializer/ToStream.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ToStream.java     18 Jun 2003 14:59:45 -0000      1.13
  +++ ToStream.java     23 Jun 2003 06:26:52 -0000      1.14
  @@ -762,7 +762,7 @@
            * will run faster in that situation.
            */
           if (m_indentAmount > 0)
  -            printSpace(m_currentElemDepth * m_indentAmount);
  +            printSpace(m_elemContext.m_currentElemDepth * m_indentAmount);
   
       }
       /**
  @@ -1240,10 +1240,10 @@
           try
           {
               final int old_start = start;
  -            if (m_startTagOpen)
  +            if (m_elemContext.m_startTagOpen)
               {
                   closeStartTag();
  -                m_startTagOpen = false;
  +                m_elemContext.m_startTagOpen = false;
               }
               m_ispreserve = true;
   
  @@ -1329,10 +1329,10 @@
               return;
           try
           {
  -            if (m_startTagOpen)
  +            if (m_elemContext.m_startTagOpen)
               {
                   closeStartTag();
  -                m_startTagOpen = false;
  +                m_elemContext.m_startTagOpen = false;
               }
   
               m_ispreserve = true;
  @@ -1376,17 +1376,17 @@
       public void characters(final char chars[], final int start, final int 
length)
           throws org.xml.sax.SAXException
       {
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               closeStartTag();
  -            m_startTagOpen = false;
  +            m_elemContext.m_startTagOpen = false;
           }
           else if (m_needToCallStartDocument)
           {
               startDocumentInternal();
           }
   
  -        if (m_cdataStartCalled || m_cdataSectionStates.peekOrFalse())
  +        if (m_cdataStartCalled || m_elemContext.m_isCdataSection)
           {
               /* either due to startCDATA() being called or due to 
                * cdata-section-elements atribute, we need this as cdata
  @@ -1411,10 +1411,10 @@
               return;
           }
   
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               closeStartTag();
  -            m_startTagOpen = false;
  +            m_elemContext.m_startTagOpen = false;
           }
   
           
  @@ -1714,20 +1714,15 @@
               /* before we over-write the current elementLocalName etc.
                * lets close out the old one (if we still need to)
                */
  -            if (m_startTagOpen)
  +            if (m_elemContext.m_startTagOpen)
               {
                   closeStartTag();
  -                m_startTagOpen = false;
  +                m_elemContext.m_startTagOpen = false;
               }
   
               if (namespaceURI != null)
                   ensurePrefixIsDeclared(namespaceURI, name);
  -
  -            // remember for later
  -            m_elementLocalName = localName;
  -            m_elementURI = namespaceURI;
  -            m_elementName = name;
  -
  +                
               m_ispreserve = false;
   
               if (shouldIndent() && m_startNewLine)
  @@ -1749,10 +1744,8 @@
           // process the attributes now, because after this SAX call they 
might be gone
           if (atts != null)
               addAttributes(atts);
  -
  -        // mark that the closing '>' of the starting tag is not yet written 
out
  -        m_startTagOpen = true;
  -        m_currentElemDepth++; // current element is one element deeper
  +            
  +        m_elemContext = m_elemContext.push(namespaceURI,localName,name);
           m_isprevtext = false;
   
                if (m_tracer != null)
  @@ -1956,18 +1949,15 @@
   
           // namespaces declared at the current depth are no longer valid
           // so get rid of them    
  -        m_prefixMap.popNamespaces(m_currentElemDepth);
  -
  -        // this element is done, so the new current element is one element 
less deep    
  -        m_currentElemDepth--;
  +        m_prefixMap.popNamespaces(m_elemContext.m_currentElemDepth);
   
           try
           {
               final java.io.Writer writer = m_writer;
  -            if (m_startTagOpen)
  +            if (m_elemContext.m_startTagOpen)
               {
                   if (m_tracer != null)
  -                    super.fireStartElem(m_elementName);
  +                    super.fireStartElem(m_elemContext.m_elementName);
                   int nAttrs = m_attributes.getLength();
                   if (nAttrs > 0)
                   {
  @@ -1996,8 +1986,6 @@
                   writer.write('/');
                   writer.write(name);
                   writer.write('>');
  -                if (m_cdataSectionElements != null)
  -                    m_cdataSectionStates.pop();
               }
           }
           catch (IOException e)
  @@ -2005,22 +1993,17 @@
               throw new SAXException(e);
           }
   
  -        if (!m_startTagOpen && m_doIndent)
  +        if (!m_elemContext.m_startTagOpen && m_doIndent)
           {
               m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop();
           }
   
           m_isprevtext = false;
  -        m_startTagOpen = false;
  -
  -        // m_disableOutputEscapingStates.pop();
  -
  -             m_elementURI = null;
  -             m_elementLocalName = null;
   
           // fire off the end element event
           if (m_tracer != null)
               super.fireEndElem(name);
  +        m_elemContext = m_elemContext.m_prev;
       }
   
       /**
  @@ -2096,12 +2079,12 @@
           {
               flushPending();
               // the prefix mapping applies to the child element (one deeper)
  -            pushDepth = m_currentElemDepth + 1;
  +            pushDepth = m_elemContext.m_currentElemDepth + 1;
           }
           else
           {
               // the prefix mapping applies to the current element
  -            pushDepth = m_currentElemDepth;
  +            pushDepth = m_elemContext.m_currentElemDepth;
           }
           pushed = m_prefixMap.pushNamespace(prefix, uri, pushDepth);
   
  @@ -2152,10 +2135,10 @@
           int start_old = start;
           if (m_inEntityRef)
               return;
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               closeStartTag();
  -            m_startTagOpen = false;
  +            m_elemContext.m_startTagOpen = false;
           }
           else if (m_needToCallStartDocument)
           {
  @@ -2234,7 +2217,7 @@
           {
               if (m_needToOutputDocTypeDecl)
               {
  -                outputDocTypeDecl(m_elementName, false);
  +                outputDocTypeDecl(m_elemContext.m_elementName, false);
                   m_needToOutputDocTypeDecl = false;
               }
               final java.io.Writer writer = m_writer;
  @@ -2346,13 +2329,13 @@
       protected void closeStartTag() throws SAXException
       {
   
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
   
               try
               {
                   if (m_tracer != null)
  -                    super.fireStartElem(m_elementName);
  +                    super.fireStartElem(m_elemContext.m_elementName);
                   int nAttrs = m_attributes.getLength();
                   if (nAttrs > 0)
                   {
  @@ -2372,7 +2355,7 @@
                * section-elements list.
                */
               if (m_cdataSectionElements != null)
  -                pushCdataSectionState();
  +                m_elemContext.m_isCdataSection = isCdataSection();
   
               if (m_doIndent)
               {
  @@ -2405,7 +2388,7 @@
           setDoctypeSystem(systemId);
           setDoctypePublic(publicId);
   
  -        m_elementName = name;
  +        m_elemContext.m_elementName = name;
           m_inDoctype = true;
       }
   
  @@ -2673,10 +2656,10 @@
                   startDocumentInternal();
                   m_needToCallStartDocument = false;
               }
  -            if (m_startTagOpen)
  +            if (m_elemContext.m_startTagOpen)
               {
                   closeStartTag();
  -                m_startTagOpen = false;
  +                m_elemContext.m_startTagOpen = false;
               }
   
               if (m_cdataTagOpen)
  
  
  
  1.7       +27 -57    
xml-xalan/java/src/org/apache/xml/serializer/SerializerBase.java
  
  Index: SerializerBase.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xml/serializer/SerializerBase.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- SerializerBase.java       28 May 2003 15:11:14 -0000      1.6
  +++ SerializerBase.java       23 Jun 2003 06:26:52 -0000      1.7
  @@ -122,34 +122,6 @@
        * true if we still need to call startDocumentInternal() 
         */
       protected boolean m_needToCallStartDocument = true; 
  -    
  -    /**
  -     * Set to true when a start tag is started, or open, but not all the
  -     * attributes or namespace information is yet collected.
  -     */
  -    protected boolean m_startTagOpen = false;
  -
  -    /**
  -     * Keeps track of the nesting depth of elements inside each other.
  -     * This is the nesting depth of the current element being processed.
  -     */
  -    int m_currentElemDepth = 0;
  -
  -    /**
  -     * The cached value of the QName of the current element
  -     */
  -    protected String m_elementName = null;
  -    
  -    /**
  -     * The cached value of the local name of the current element
  -     */
  -    protected String m_elementLocalName = null;
  -    
  -    /**
  -     * The cached value of the URI of the current element
  -     */
  -    protected String m_elementURI = null;
  -
   
       /** True if a trailing "]]>" still needs to be written to be
        * written out. Used to merge adjacent CDATA sections
  @@ -171,13 +143,6 @@
       /** This flag is set while receiving events from the external DTD */
       protected boolean m_inExternalDTD = false;
   
  -    /** When an element starts, if its name is in the cdata-section-names 
list
  -     * then push a True on the stack, otherwise push a False.
  -     * at the end of an element the value is poped.
  -     * It is True if the text of the element should be in CDATA section 
blocks. 
  -     */
  -    protected final BoolStack m_cdataSectionStates = new BoolStack();
  -
       /**
        * The System ID for the doc type.
        */
  @@ -269,6 +234,14 @@
        * other fire... methods can flush this writer when tracing.
        */
       protected java.io.Writer m_writer = null;    
  +    
  +    /**
  +     * A reference to "stack frame" corresponding to
  +     * the current element. Such a frame is pushed at a startElement()
  +     * and popped at an endElement(). This frame contains information about
  +     * the element, such as its namespace URI. 
  +     */
  +    protected ElemContext m_elemContext = new ElemContext();
   
       /**
        * Receive notification of a comment.
  @@ -381,7 +354,7 @@
           String value)
           throws SAXException
       {
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               addAttributeAlways(uri, localName, rawName, type, value);
           }
  @@ -444,7 +417,7 @@
        */
       public void addAttribute(String name, final String value)
       {
  -        if (m_startTagOpen)
  +        if (m_elemContext.m_startTagOpen)
           {
               final String patchedName = patchName(name);
               final String localName = getLocalName(patchedName);
  @@ -794,26 +767,28 @@
        * false). Other hidden parameters are the current elements namespaceURI,
        * localName and qName
        */
  -    protected void pushCdataSectionState()
  +    protected boolean isCdataSection()
       {
   
  -        boolean b;
  +        boolean b = false;
   
           if (null != m_cdataSectionElements)
           {
  -            b = false;
  -            if (m_elementLocalName == null)
  -                m_elementLocalName = getLocalName(m_elementName);
  -            if (m_elementURI == null)
  +            if (m_elemContext.m_elementLocalName == null)
  +                m_elemContext.m_elementLocalName = 
  +                    getLocalName(m_elemContext.m_elementName);
  +            if (m_elemContext.m_elementURI == null)
               {
  -                String prefix = getPrefixPart(m_elementName);
  +                String prefix = getPrefixPart(m_elemContext.m_elementName);
                   if (prefix != null)
  -                    m_elementURI = m_prefixMap.lookupNamespace(prefix);
  +                    m_elemContext.m_elementURI = 
  +                        m_prefixMap.lookupNamespace(prefix);
   
               }
   
  -            if ((null != m_elementURI) && m_elementURI.length() == 0)
  -                m_elementURI = null;
  +            if ((null != m_elemContext.m_elementURI) 
  +                && m_elemContext.m_elementURI.length() == 0)
  +                m_elemContext.m_elementURI = null;
   
               int nElems = m_cdataSectionElements.size();
   
  @@ -822,16 +797,16 @@
               {
                   String uri = (String) m_cdataSectionElements.elementAt(i);
                   String loc = (String) m_cdataSectionElements.elementAt(i + 
1);
  -                if (loc.equals(m_elementLocalName)
  -                    && subPartMatch(m_elementURI, uri))
  +                if (loc.equals(m_elemContext.m_elementLocalName)
  +                    && subPartMatch(m_elemContext.m_elementURI, uri))
                   {
                       b = true;
   
                       break;
                   }
               }
  -            m_cdataSectionStates.push(b);
           }
  +        return b;
       }
   
       /**
  @@ -1014,7 +989,7 @@
        */
       public void fatalError(SAXParseException exc) throws SAXException {
           
  -      m_startTagOpen = false;
  +      m_elemContext.m_startTagOpen = false;
   
       }
   
  @@ -1290,14 +1265,10 @@
       {
        this.m_attributes.clear();
        this.m_cdataSectionElements = null;
  -     this.m_cdataSectionStates.clear();
  -     this.m_currentElemDepth = 0;
  +        this.m_elemContext = new ElemContext();
        this.m_doctypePublic = null;
        this.m_doctypeSystem = null;
        this.m_doIndent = false;
  -     this.m_elementLocalName = null;
  -     this.m_elementLocalName = null;
  -     this.m_elementName = null;
        this.m_encoding = null;
        this.m_indentAmount = 0;
        this.m_inEntityRef = false;
  @@ -1311,7 +1282,6 @@
        this.m_sourceLocator = null;
        this.m_standalone = null;
        this.m_standaloneWasSpecified = false;
  -     this.m_startTagOpen = false;
        this.m_tracer = null;
        this.m_transformer = null;
        this.m_version = null;
  
  
  
  1.1                  
xml-xalan/java/src/org/apache/xml/serializer/ElemContext.java
  
  Index: ElemContext.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2003, International Business
   * Machines, Inc., http://www.ibm.com.  For more information on the Apache
   * Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.xml.serializer;
  
  /**
   * This class is a stack frame that consists of 
   * information about the element currently being processed 
   * by a serializer. Consider this example:
   * <pre>
   *   <A>
   *     <B1>
   *     </B1>
   *     <B2>
   *     </B2>
   *   <A>
   * </pre> 
   * 
   * A stack frame will be pushed for "A" at depth 1, 
   * then another one for "B1" at depth 2.
   * Then "B1" stackframe is popped.  When the stack frame for "B2" is 
   * pushed, this implementation re-uses the old stack fram object used
   * by "B1" to be efficient at not creating too many of these object.
   * 
   * This is by no means a public class, and neither are its fields or methods,
   * they are all helper fields for a serializer.
   * 
   * The purpose of this class is to be more consistent with pushing information
   * when a new element is being serialized and more quickly restoring the old
   * information about the parent element with a simple pop() when the
   * child element is done.  Previously there was some redundant and error-prone
   * calculations going on to retore information.
   * 
   */
  class ElemContext
  {
      // Fields that form the context of the element
  
      /**
       * The nesting depth of the element inside other elements.
       */
      final int m_currentElemDepth;
  
      /** HTML field, the element description of the HTML element */
      ElemDesc m_elementDesc = null;
  
      /**
       * The local name of the element.
       */
      String m_elementLocalName = null;
  
      /**
       * The fully qualified name of the element (with prefix, if any).
       */
      String m_elementName = null;
  
      /**
       * The URI of the element.
       */
      String m_elementURI = null;
  
      /** If the element is in the cdata-section-names list
       * then the value is true. If it is true the text children of the element
       * should be output in CDATA section blocks. 
       */
      boolean m_isCdataSection;
  
      /** True if the current element has output escaping disabled.
       * This is true for SCRIPT and STYLE elements. 
       */
      boolean m_isRaw = false;
  
      /** The next element "stack frame". This value will only be
       * set once as deeper stack frames are not deleted when popped off,
       * but are rather re-used when a push is required.
       * 
       * This makes for very fast pushing and popping of stack frames 
       * because very few stack frame objects are ever created, they are
       * mostly re-used.  This re-use saves object creation but it also means
       * that connections between the frames via m_next and m_prev
       * never changes either. Just the contents of the frames change
       * as they are re-used. Only the reference to the current stack frame, 
which
       * is held by the serializer is changed via a quick pop() or push().
       */
      private ElemContext m_next;
  
      /** The previous element "stack frame". */
      final ElemContext m_prev;
  
      /**
       * Set to true when a start tag is started, or open, but not all the
       * attributes or namespace information is yet collected.
       */
      boolean m_startTagOpen = false;
  
      /**
       * Constructor to create the root of the element contexts. 
       *
       */
      ElemContext()
      {
          // this assignment means can never pop this context off
          m_prev = this;
          // depth 0 because it doesn't correspond to any element
          m_currentElemDepth = 0;
      }
  
      /**
       * Constructor to create the "stack frame" for a given element depth.
       * 
       * This implementation will re-use the context at each depth. If
       * a documents deepest element depth is N then there will be (N+1)
       * such objects created, no more than that.
       * 
       * @param previous The "stack frame" corresponding to the new
       * elements parent element.
       */
      private ElemContext(final ElemContext previous)
      {
          m_prev = previous;
          m_currentElemDepth = previous.m_currentElemDepth + 1;
      }
  
      /**
       * Pop the current "stack frame".
       * @return Returns the parent "stack frame" of the one popped.
       */
      final ElemContext pop()
      {
          /* a very simple pop.  No clean up is done of the deeper
           * stack frame.  All deeper stack frames are still attached
           * but dormant, just waiting to be re-used.
           */
          return this.m_prev;
      }
  
      /**
       * This method pushes an element "stack frame" 
       * but with no initialization of values in that frame.
       * This method is used for optimization purposes, like when pushing
       * a stack frame for an HTML "IMG" tag which has no children and
       * the stack frame will almost immediately be popped.
       */
      final ElemContext push()
      {
          ElemContext frame = this.m_next;
          if (frame == null)
          {
              /* We have never been at this depth yet, and there is no
               * stack frame to re-use, so we now make a new one.
               */
              frame = new ElemContext(this);
              this.m_next = frame;
          }
          /*
           * We shouldn't need to set this true because we should just
           * be pushing a dummy stack frame that will be instantly popped.
           * Yet we need to be ready in case this element does have
           * unexpected children.
           */
          frame.m_startTagOpen = true;
          return frame;
      }
      
      /**
       * Push an element context on the stack. This context keeps track of
       * information gathered about the element.
       * @param uri The URI for the namespace for the element name, 
       * can be null if it is not yet known.
       * @param localName The local name of the element (no prefix),  
       * can be null.
       * @param qName The qualified name (with prefix, if any) 
       * of the element, this parameter is required.
       */
      final ElemContext push(
          final String uri,
          final String localName,
          final String qName)
      {
          ElemContext frame = this.m_next;
          if (frame == null)
          {
              /* We have never been at this depth yet, and there is no
               * stack frame to re-use, so we now make a new one.
               */
              frame = new ElemContext(this);
              this.m_next = frame;
          }
  
          // Initialize, or reset values in the new or re-used stack frame.
          frame.m_elementName = qName;
          frame.m_elementLocalName = localName;
          frame.m_elementURI = uri;
          frame.m_isCdataSection = false;
          frame.m_startTagOpen = true;
  
          // is_Raw is already set in the HTML startElement() method
          // frame.m_isRaw = false; 
          return frame;
      }
  }
  
  

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

Reply via email to