8223291: Whitespace is added to CDATA tags when using OutputKeys.INDENT to format XML
authorjoehw
Wed, 03 Jul 2019 16:30:19 +0000
changeset 55575 25165403c62e
parent 55574 0246f81c1dcd
child 55576 4d193e40e7af
8223291: Whitespace is added to CDATA tags when using OutputKeys.INDENT to format XML Reviewed-by: dfuchs, lancea
src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java
src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java
src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java
test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java
test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.out
test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.out
test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.out
test/jaxp/javax/xml/jaxp/unittest/transform/OutputPropertiesTest.java
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java	Wed Jul 03 17:52:56 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java	Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,7 +40,7 @@
  * because it is used from another package.
  *
  * @xsl.usage internal
- * @LastModified: Sept 2018
+ * @LastModified: July 2019
  */
 public final class ToHTMLStream extends ToStream
 {
@@ -719,7 +719,7 @@
     public final void endDocument() throws org.xml.sax.SAXException
     {
         if (m_doIndent) {
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
         flushPending();
         if (m_doIndent && !m_isprevtext)
@@ -782,7 +782,7 @@
         if (m_doIndent) {
             // will add extra one if having namespace but no matter
             m_childNodeNum++;
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
         ElemContext elemContext = m_elemContext;
 
@@ -923,7 +923,7 @@
         throws org.xml.sax.SAXException
     {
         if (m_doIndent) {
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
         // deal with any pending issues
         if (m_cdataTagOpen)
@@ -1645,7 +1645,7 @@
     {
         if (m_doIndent) {
             m_childNodeNum++;
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
         // Process any pending starDocument and startElement first.
         flushPending();
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java	Wed Jul 03 17:52:56 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java	Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -51,7 +51,7 @@
  * serializers (xml, html, text ...) that write output to a stream.
  *
  * @xsl.usage internal
- * @LastModified: Sept 2018
+ * @LastModified: July 2019
  */
 abstract public class ToStream extends SerializerBase {
 
@@ -1231,7 +1231,7 @@
                 m_elemContext.m_startTagOpen = false;
             }
 
-            if (!m_cdataTagOpen && shouldIndent())
+            if (!m_cdataTagOpen && shouldIndentForText())
                 indent();
 
             boolean writeCDataBrackets =
@@ -1270,6 +1270,7 @@
                     closeCDATA();
             }
 
+            m_isprevtext = true;
             // time to fire off CDATA event
             if (m_tracer != null)
                 super.fireCDATAEvent(ch, old_start, length);
@@ -1536,11 +1537,13 @@
     }
 
     /**
-     * Used to flush the buffered characters when indentation is on, this method
-     * will be called when the next node is traversed.
+     * Flushes the buffered characters when indentation is on. This method
+     * is called before the next node is traversed.
      *
+     * @param isText indicates whether the node to be traversed is text
+     * @throws org.xml.sax.SAXException
      */
-    final protected void flushCharactersBuffer() throws SAXException {
+    final protected void flushCharactersBuffer(boolean isText) throws SAXException {
         try {
             if (shouldFormatOutput() && m_charactersBuffer.isAnyCharactersBuffered()) {
                 if (m_elemContext.m_isCdataSection) {
@@ -1553,7 +1556,9 @@
                     return;
                 }
 
-                m_childNodeNum++;
+                if (!isText) {
+                    m_childNodeNum++;
+                }
                 boolean skipBeginningNewlines = false;
                 if (shouldIndentForText()) {
                     indent();
@@ -1846,7 +1851,7 @@
 
         if (m_doIndent) {
             m_childNodeNum++;
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
 
         if (m_needToCallStartDocument)
@@ -2117,7 +2122,7 @@
             return;
 
         if (m_doIndent) {
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
         // namespaces declared at the current depth are no longer valid
         // so get rid of them
@@ -2309,7 +2314,7 @@
             return;
         if (m_doIndent) {
             m_childNodeNum++;
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
         if (m_elemContext.m_startTagOpen)
         {
@@ -2491,8 +2496,7 @@
     public void startCDATA() throws org.xml.sax.SAXException
     {
         if (m_doIndent) {
-            m_childNodeNum++;
-            flushCharactersBuffer();
+            flushCharactersBuffer(true);
         }
 
         m_cdataStartCalled = true;
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java	Wed Jul 03 17:52:56 2019 +0200
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java	Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,6 +40,7 @@
  * be viewed as internal or package private, this is not an API.
  *
  * @xsl.usage internal
+ * @LastModified: July 2019
  */
 public final class ToXMLStream extends ToStream
 {
@@ -200,7 +201,7 @@
     public void endDocument() throws org.xml.sax.SAXException
     {
         if (m_doIndent) {
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
         flushPending();
         if (m_doIndent && !m_isprevtext)
@@ -267,7 +268,7 @@
 
         if (m_doIndent) {
             m_childNodeNum++;
-            flushCharactersBuffer();
+            flushCharactersBuffer(false);
         }
         flushPending();
 
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java	Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java	Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
 
 /*
  * @test
- * @bug 6439439 8087303 8174025
+ * @bug 6439439 8087303 8174025 8223291
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  * @run testng/othervm -DrunSecMngr=true common.prettyprint.PrettyPrintTest
  * @run testng/othervm common.prettyprint.PrettyPrintTest
@@ -382,7 +382,6 @@
     private Document toXmlDocument(String xmlString) throws Exception {
         InputSource xmlInputSource = new InputSource(new StringReader(xmlString));
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-        dbf.setValidating(true);
         DocumentBuilder xmlDocumentBuilder = dbf.newDocumentBuilder();
         Document node = xmlDocumentBuilder.parse(xmlInputSource);
         return node;
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.out	Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.out	Wed Jul 03 16:30:19 2019 +0000
@@ -1,3 +1,1 @@
-<a>
-    <![CDATA[ ]]>
-</a>
+<a><![CDATA[ ]]></a>
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.out	Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.out	Wed Jul 03 16:30:19 2019 +0000
@@ -1,5 +1,3 @@
-<a>
-    <![CDATA[  abc def 
+<a><![CDATA[  abc def 
 line2 &a 
- test]]>
-</a>
+ test]]></a>
--- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.out	Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.out	Wed Jul 03 16:30:19 2019 +0000
@@ -1,6 +1,5 @@
 <root>
-         t
-    <![CDATA[ ]]>
+     t<![CDATA[ ]]>
     t   
     
     <child1/>
--- a/test/jaxp/javax/xml/jaxp/unittest/transform/OutputPropertiesTest.java	Wed Jul 03 17:52:56 2019 +0200
+++ b/test/jaxp/javax/xml/jaxp/unittest/transform/OutputPropertiesTest.java	Wed Jul 03 16:30:19 2019 +0000
@@ -24,21 +24,79 @@
 package transform;
 
 import java.io.StringReader;
+import java.io.StringWriter;
 import java.util.Properties;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 import org.testng.Assert;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
 
 /*
  * @test
- * @bug 8219705
+ * @bug 8219705 8223291
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  * @run testng transform.OutputPropertiesTest
  * @summary Verifies the output properties are set correctly
  */
 public class OutputPropertiesTest {
+    /*
+       DataProvider: for testing indentation
+       Data: xml, expected result
+     */
+    @DataProvider(name = "Indentation")
+    public Object[][] getData() {
+        String mix = "\n" +
+                "        abc\n" +
+                "        mix\n" +
+                "        xyz\n" +
+                "    ";
+        return new Object[][]{
+            {"abc<![CDATA[data]]>xyz", "abcdataxyz"},
+            {"abc<![CDATA[ & ]]>xyz", "abc & xyz"},
+            {"<![CDATA[data]]>", "data"},
+            {"abc<mix>mix</mix>xyz", mix}
+        };
+    }
+
+
+    /**
+     * bug 8223291
+     * Verifies that no extra indentation is added for CDATA.
+     * @param xml the xml content to be tested
+     * @param expected the expected result
+     * @throws Exception
+     */
+    @Test(dataProvider = "Indentation")
+    public void testIndentation(String xml, String expected) throws Exception
+    {
+        StreamSource source = new StreamSource(new StringReader("<foo><bar>" + xml + "</bar></foo>"));
+        StreamResult result = new StreamResult(new StringWriter());
+
+        Transformer tform = TransformerFactory.newInstance().newTransformer();
+        tform.setOutputProperty(OutputKeys.INDENT, "yes");
+        tform.transform(source, result);
+
+        String xml1 = result.getWriter().toString();
+
+        Document document = DocumentBuilderFactory.newInstance()
+            .newDocumentBuilder()
+            .parse(new InputSource(new StringReader(xml1)));
+
+        String resultData = document.getElementsByTagName("bar")
+            .item(0)
+            .getTextContent();
+
+        Assert.assertEquals(resultData, expected);
+    }
+
     @Test
     public void testOutputProperties() throws Exception {
         String xslData = "<?xml version='1.0'?>"
@@ -70,4 +128,5 @@
                     prNames[i] + ": actual: " + value + ", expected: " + prValues[i]);
         }
     }
+
 }