You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mi...@apache.org on 2003/10/21 21:27:37 UTC

cvs commit: xml-xalan/java/src/org/apache/xml/serializer ToXMLSAXHandler.java ToSAXHandler.java

minchau     2003/10/21 12:27:37

  Modified:    java/src/org/apache/xml/serializer ToXMLSAXHandler.java
                        ToSAXHandler.java
  Log:
  PR: bugzilla 23812
  Submitted by:	Brian Minchau
  Reviewed by:	Henry Zongaro
  Fixes incorrect handling of CDATA by a ToXMLSAXHandler. 
  The CDATA was defined by calls to the LexicalHandler methods:
  startCDATA()
  endCDATA()
  
  Henry would rather have a new flushPending() method which does not
  flush a generated endCDATA() call, but I copied the contents of flushPending()
  to the top of ToXMLSAXHandler.character(char[] chars, int off, int len)
  anyways.  I didn't want to put a new flushPending() method on a SerializationHandler
  interface.   I'm not completely happy with either choice so I left it as-was  - bjm
  
  Revision  Changes    Path
  1.9       +80 -48    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.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ToXMLSAXHandler.java	7 Jul 2003 06:23:51 -0000	1.8
  +++ ToXMLSAXHandler.java	21 Oct 2003 19:27:37 -0000	1.9
  @@ -252,14 +252,26 @@
       }
   
       /**
  -     * Closes the open cdata tag
  +     * Closes ane open cdata tag, and
  +     * unlike the this.endCDATA() method (from the LexicalHandler) interface,
  +     * this "internal" method will send the endCDATA() call to the wrapped
  +     * handler.
  +     * 
        */
       public void closeCDATA() throws SAXException
       {
   
           // Output closing bracket - "]]>"
  -        m_saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
  -        m_cdataTagOpen = false;
  +        if (m_lexHandler != null && m_cdataTagOpen) {
  +            m_lexHandler.endCDATA();
  +        }
  +        
  +
  +        // There are no longer any calls made to 
  +        // m_lexHandler.startCDATA() without a balancing call to
  +        // m_lexHandler.endCDATA()
  +        // so we set m_cdataTagOpen to false to remember this.
  +        m_cdataTagOpen = false;        
       }
   
       /**
  @@ -435,8 +447,27 @@
        */
       public void endCDATA() throws SAXException
       {
  -        if (m_lexHandler != null)
  -            m_lexHandler.endCDATA();
  +        /* Normally we would do somthing with this but we ignore it.
  +         * The neccessary call to m_lexHandler.endCDATA() will be made
  +         * in flushPending().
  +         * 
  +         * This is so that if we get calls like these:
  +         *   this.startCDATA();
  +         *   this.characters(chars1, off1, len1);
  +         *   this.endCDATA();
  +         *   this.startCDATA();
  +         *   this.characters(chars2, off2, len2);
  +         *   this.endCDATA();
  +         * 
  +         * that we will only make these calls to the wrapped handlers:
  +         * 
  +         *   m_lexHandler.startCDATA();
  +         *   m_saxHandler.characters(chars1, off1, len1);
  +         *   m_saxHandler.characters(chars1, off2, len2);
  +         *   m_lexHandler.endCDATA();
  +         * 
  +         * We will merge adjacent CDATA blocks.
  +         */ 
       }
   
       /**
  @@ -515,18 +546,35 @@
   
       public void characters(char[] ch, int off, int len) throws SAXException
       {
  -        // System.out.println("SAXXMLOutput.characters ch = " + new String(ch, off, len));
  -
  -        flushPending();
  +        // We do the first two things in flushPending() but we don't
  +        // close any open CDATA calls.        
  +        if (m_needToCallStartDocument)
  +        {
  +            startDocumentInternal();
  +            m_needToCallStartDocument = false;
  +        }
   
  -        if (m_elemContext.m_isCdataSection)
  +        if (m_elemContext.m_startTagOpen)
           {
  -            startCDATA(ch, off, len);
  +            closeStartTag();
  +            m_elemContext.m_startTagOpen = false;
           }
  -        else
  +
  +        if (m_elemContext.m_isCdataSection && !m_cdataTagOpen
  +        && m_lexHandler != null) 
           {
  -            m_saxHandler.characters(ch, off, len);
  +            m_lexHandler.startCDATA();
  +            // We have made a call to m_lexHandler.startCDATA() with
  +            // no balancing call to m_lexHandler.endCDATA()
  +            // so we set m_cdataTagOpen true to remember this.
  +            m_cdataTagOpen = true;
           }
  +        
  +        /* If there are any occurances of "]]>" in the character data
  +         * let m_saxHandler worry about it, we've already warned them with
  +         * the previous call of m_lexHandler.startCDATA();
  +         */ 
  +        m_saxHandler.characters(ch, off, len);
   
   		// time to generate characters event
   		if (m_tracer != null)
  @@ -598,47 +646,31 @@
   
       public void startCDATA() throws SAXException
       {
  -
  -        // Output start bracket - "<![CDATA["
  -        m_saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);
  -        m_cdataTagOpen = true;
  -
  -    }
  -
  -    /**
  -     * Utility method - pass a whole charactes as CDATA to SAX handler
  -     */
  -    private void startCDATA(char[] ch, int off, int len) throws SAXException
  -    {
  -        final int limit = off + len;
  -        int offset = off;
  -
  -        // Output start bracket - "<![CDATA["
  -        m_saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);
  -
  -        // Detect any occurence of "]]>" in the character array
  -        for (int i = offset; i < limit - 2; i++)
  +        /* m_cdataTagOpen can only be true here if we have ignored the
  +         * previous call to this.endCDATA() and the previous call 
  +         * this.startCDATA() before that is still "open". In this way
  +         * we merge adjacent CDATA. If anything else happened after the 
  +         * ignored call to this.endCDATA() and this call then a call to 
  +         * flushPending() would have been made which would have
  +         * closed the CDATA and set m_cdataTagOpen to false.
  +         */
  +        if (!m_cdataTagOpen ) 
           {
  -            if (ch[i] == ']' && ch[i + 1] == ']' && ch[i + 2] == '>')
  -            {
  -                m_saxHandler.characters(ch, offset, i - offset);
  -                m_saxHandler.characters(CNTCDATA, 0, CNTCDATA.length);
  -                offset = i + 3;
  -                i += 2; // Skip next chars ']' and '>'
  -            }
  -        }
  +            flushPending();
  +            if (m_lexHandler != null) {
  +                m_lexHandler.startCDATA();
   
  -        // Output the remaining characters
  -        if (offset < limit)
  -        {
  -            m_saxHandler.characters(ch, offset, limit - offset);
  -        }
  -        m_cdataTagOpen = true;
  +                // We have made a call to m_lexHandler.startCDATA() with
  +                // no balancing call to m_lexHandler.endCDATA()
  +                // so we set m_cdataTagOpen true to remember this.                
  +                m_cdataTagOpen = true;     
  +            }              
  +        }        
       }
   
       /**
  -    * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
  -    */
  +     * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
  +     */
       public void startElement(
       String namespaceURI,
       String localName,
  
  
  
  1.8       +8 -4      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.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ToSAXHandler.java	6 Oct 2003 14:33:07 -0000	1.7
  +++ ToSAXHandler.java	21 Oct 2003 19:27:37 -0000	1.8
  @@ -357,7 +357,7 @@
       }
       
       /**
  -     * This method gets the nodes value as a String and uses that String as if
  +     * This method gets the node's value as a String and uses that String as if
        * it were an input character notification.
        * @param node the Node to serialize
        * @throws org.xml.sax.SAXException
  @@ -371,9 +371,13 @@
               m_state.setCurrentNode(node);
           }
           
  -        // do what the stream serializers do
  -        super.characters(node);
  -       }    
  +        // Get the node's value as a String and use that String as if
  +        // it were an input character notification.
  +        String data = node.getNodeValue();
  +        if (data != null) {
  +            this.characters(data);
  +        }
  +    }    
   
       /**
        * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org