8139584: XMLStreamWriterImpl does not write 'standalone' property
authorjoehw
Fri, 07 Oct 2016 10:51:19 -0700
changeset 41432 c4036f85c0c5
parent 41431 62f1dfefd681
child 41433 cb61e6c52097
8139584: XMLStreamWriterImpl does not write 'standalone' property Reviewed-by: lancea
jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLDOMWriterImpl.java
jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLEventWriterImpl.java
jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterBase.java
jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java
jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamWriterTest/XMLStreamWriterTest.java
--- a/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLDOMWriterImpl.java	Thu Oct 06 18:05:53 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLDOMWriterImpl.java	Fri Oct 07 10:51:19 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -25,6 +25,8 @@
 
 package com.sun.xml.internal.stream.writers;
 
+import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl;
+import com.sun.org.apache.xerces.internal.dom.DocumentImpl;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import javax.xml.XMLConstants;
@@ -57,7 +59,7 @@
  * Change StringBuffer to StringBuilder, when JDK 1.5 will be minimum requirement for SJSXP.
  */
 
-public class XMLDOMWriterImpl implements XMLStreamWriter  {
+public class XMLDOMWriterImpl implements XMLStreamWriterBase  {
 
 
     private Document ownerDoc = null;
@@ -552,7 +554,7 @@
      * @throws javax.xml.stream.XMLStreamException {@inheritDoc}
      */
     public void writeStartDocument(String version) throws XMLStreamException {
-        ownerDoc.setXmlVersion(version);
+        writeStartDocument(null, version, false, false);
     }
 
     /**
@@ -563,8 +565,20 @@
      * @throws javax.xml.stream.XMLStreamException {@inheritDoc}
      */
     public void writeStartDocument(String encoding, String version) throws XMLStreamException {
+        writeStartDocument(encoding, version, false, false);
+    }
+
+    @Override
+    public void writeStartDocument(String encoding, String version, boolean standalone, boolean standaloneSet) throws XMLStreamException {
+        if (encoding != null && ownerDoc.getClass().isAssignableFrom(DocumentImpl.class)) {
+            ((DocumentImpl)ownerDoc).setXmlEncoding(encoding);
+        }
+
         ownerDoc.setXmlVersion(version);
-        //TODO: What to do with encoding.-Venu
+
+        if (standaloneSet) {
+            ownerDoc.setXmlStandalone(standalone);
+        }
     }
 
     /**
--- a/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLEventWriterImpl.java	Thu Oct 06 18:05:53 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLEventWriterImpl.java	Fri Oct 07 10:51:19 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -49,14 +49,14 @@
 public class XMLEventWriterImpl implements XMLEventWriter{
 
     //delegate everything to XMLStreamWriter..
-    private XMLStreamWriter fStreamWriter ;
+    private final XMLStreamWriterBase fStreamWriter ;
     private static final boolean DEBUG = false;
     /**
      *
      * @param streamWriter
      */
     public XMLEventWriterImpl(XMLStreamWriter streamWriter){
-        fStreamWriter = streamWriter;
+        fStreamWriter = (XMLStreamWriterBase)streamWriter;
     }
 
     /**
@@ -89,7 +89,8 @@
                 StartDocument startDocument = (StartDocument)xMLEvent ;
                 if (DEBUG)System.out.println("Adding StartDocument = " + startDocument.toString());
                 try {
-                   fStreamWriter.writeStartDocument(startDocument.getCharacterEncodingScheme(), startDocument.getVersion());
+                   fStreamWriter.writeStartDocument(startDocument.getCharacterEncodingScheme(), startDocument.getVersion(),
+                           startDocument.isStandalone(), startDocument.standaloneSet());
                 }catch(XMLStreamException e) {
                     fStreamWriter.writeStartDocument(startDocument.getVersion());
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterBase.java	Fri Oct 07 10:51:19 2016 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.xml.internal.stream.writers;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ * Base class for shared methods among XMLStreamWriter implementations.
+ */
+public interface XMLStreamWriterBase extends XMLStreamWriter {
+    /**
+     * Writes the XML declaration.
+     *
+     * @param encoding the specified encoding
+     * @param version the specified version
+     * @param standalone the flag indicating whether it is standalone
+     * @param standaloneSet the flag indicating whether the standalone attribute is set
+     * @throws XMLStreamException in case of an IOException
+     */
+    public void writeStartDocument(String encoding, String version,
+            boolean standalone, boolean standaloneSet)
+            throws XMLStreamException;
+}
--- a/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java	Thu Oct 06 18:05:53 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java	Fri Oct 07 10:51:19 2016 -0700
@@ -71,7 +71,7 @@
  * @author Santiago.Pericas-Geertsen@sun.com
  * @author Sunitha.Reddy@sun.com
  */
-public final class XMLStreamWriterImpl extends AbstractMap implements XMLStreamWriter {
+public final class XMLStreamWriterImpl extends AbstractMap implements XMLStreamWriterBase {
 
     public static final String START_COMMENT = "<!--";
     public static final String END_COMMENT = "-->";
@@ -1112,90 +1112,55 @@
     }
 
     /**
-     * @throws XMLStreamException
+     * Writes the XML declaration.
+     *
+     * @throws XMLStreamException in case of an IOException
      */
     public void writeStartDocument() throws XMLStreamException {
-        try {
-            fWriter.write(DEFAULT_XMLDECL);
-        } catch (IOException ex) {
-            throw new XMLStreamException(ex);
-        }
+        writeStartDocument(null, null, false, false);
     }
 
     /**
-     * @param version
-     * @throws XMLStreamException
+     * Writes the XML declaration.
+     *
+     * @param version the specified version
+     * @throws XMLStreamException in case of an IOException
      */
     public void writeStartDocument(String version) throws XMLStreamException {
-        try {
-            if ((version == null) || version.equals("")) {
-                writeStartDocument();
-
-                return;
-            }
-
-            fWriter.write("<?xml version=\"");
-            fWriter.write(version);
-            fWriter.write("\"");
-
-            //fWriter.write(DEFAULT_ENCODING);
-            fWriter.write("?>");
-        } catch (IOException ex) {
-            throw new XMLStreamException(ex);
-        }
+        writeStartDocument(null, version, false, false);
     }
 
     /**
-     * @param encoding
-     * @param version
-     * @throws XMLStreamException
+     * Writes the XML declaration.
+     *
+     * @param encoding the specified encoding
+     * @param version the specified version
+     * @throws XMLStreamException in case of an IOException
      */
+    @Override
     public void writeStartDocument(String encoding, String version)
         throws XMLStreamException {
-        //Revisit : What about standalone ?
-        try {
-            if ((encoding == null) && (version == null)) {
-                writeStartDocument();
+        writeStartDocument(encoding, version, false, false);
+    }
 
-                return;
-            }
+    @Override
+    public void writeStartDocument(String encoding, String version,
+            boolean standalone, boolean standaloneSet)
+        throws XMLStreamException {
 
-            if (encoding == null) {
-                writeStartDocument(version);
-
+        try {
+            if ((encoding == null || encoding.length() == 0)
+                    && (version == null || version.length() == 0)
+                    && (!standaloneSet)) {
+                fWriter.write(DEFAULT_XMLDECL);
                 return;
             }
 
-            String streamEncoding = null;
-            if (fWriter instanceof OutputStreamWriter) {
-                streamEncoding = ((OutputStreamWriter) fWriter).getEncoding();
-            }
-            else if (fWriter instanceof UTF8OutputStreamWriter) {
-                streamEncoding = ((UTF8OutputStreamWriter) fWriter).getEncoding();
-            }
-            else if (fWriter instanceof XMLWriter) {
-                streamEncoding = ((OutputStreamWriter) ((XMLWriter)fWriter).getWriter()).getEncoding();
+            // Verify the encoding before writing anything
+            if (encoding != null && !encoding.equals("")) {
+                verifyEncoding(encoding);
             }
 
-            if (streamEncoding != null && !streamEncoding.equalsIgnoreCase(encoding)) {
-                // If the equality check failed, check for charset encoding aliases
-                boolean foundAlias = false;
-                Set aliases = Charset.forName(encoding).aliases();
-                for (Iterator it = aliases.iterator(); !foundAlias && it.hasNext(); ) {
-                    if (streamEncoding.equalsIgnoreCase((String) it.next())) {
-                        foundAlias = true;
-                    }
-                }
-                // If no alias matches the encoding name, then report error
-                if (!foundAlias) {
-                    throw new XMLStreamException("Underlying stream encoding '"
-                            + streamEncoding
-                            + "' and input paramter for writeStartDocument() method '"
-                            + encoding + "' do not match.");
-                }
-            }
-
-
             fWriter.write("<?xml version=\"");
 
             if ((version == null) || version.equals("")) {
@@ -1204,11 +1169,20 @@
                 fWriter.write(version);
             }
 
-            if (!encoding.equals("")) {
+            if (encoding != null && !encoding.equals("")) {
                 fWriter.write("\" encoding=\"");
                 fWriter.write(encoding);
             }
 
+            if (standaloneSet) {
+                fWriter.write("\" standalone=\"");
+                if (standalone) {
+                    fWriter.write("yes");
+                } else {
+                    fWriter.write("no");
+                }
+            }
+
             fWriter.write("\"?>");
         } catch (IOException ex) {
             throw new XMLStreamException(ex);
@@ -1216,6 +1190,45 @@
     }
 
     /**
+     * Verifies that the encoding is consistent between the underlying encoding
+     * and that specified.
+     *
+     * @param encoding the specified encoding
+     * @throws XMLStreamException if they do not match
+     */
+    private void verifyEncoding(String encoding) throws XMLStreamException {
+
+        String streamEncoding = null;
+        if (fWriter instanceof OutputStreamWriter) {
+            streamEncoding = ((OutputStreamWriter) fWriter).getEncoding();
+        }
+        else if (fWriter instanceof UTF8OutputStreamWriter) {
+            streamEncoding = ((UTF8OutputStreamWriter) fWriter).getEncoding();
+        }
+        else if (fWriter instanceof XMLWriter) {
+            streamEncoding = ((OutputStreamWriter) ((XMLWriter)fWriter).getWriter()).getEncoding();
+        }
+
+        if (streamEncoding != null && !streamEncoding.equalsIgnoreCase(encoding)) {
+            // If the equality check failed, check for charset encoding aliases
+            boolean foundAlias = false;
+            Set aliases = Charset.forName(encoding).aliases();
+            for (Iterator it = aliases.iterator(); !foundAlias && it.hasNext(); ) {
+                if (streamEncoding.equalsIgnoreCase((String) it.next())) {
+                    foundAlias = true;
+                }
+            }
+            // If no alias matches the encoding name, then report error
+            if (!foundAlias) {
+                throw new XMLStreamException("Underlying stream encoding '"
+                        + streamEncoding
+                        + "' and input paramter for writeStartDocument() method '"
+                        + encoding + "' do not match.");
+            }
+        }
+    }
+
+    /**
      * @param localName
      * @throws XMLStreamException
      */
--- a/jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamWriterTest/XMLStreamWriterTest.java	Thu Oct 06 18:05:53 2016 -0700
+++ b/jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamWriterTest/XMLStreamWriterTest.java	Fri Oct 07 10:51:19 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -20,21 +20,29 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package stream.XMLStreamWriterTest;
 
 import java.io.StringWriter;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLEventWriter;
 
 import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.transform.dom.DOMResult;
 
 import org.testng.Assert;
 import org.testng.annotations.Listeners;
 import org.testng.annotations.Test;
+import org.w3c.dom.Document;
 
 /*
  * @test
- * @bug 6347190
+ * @bug 6347190 8139584
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  * @run testng/othervm -DrunSecMngr=true stream.XMLStreamWriterTest.XMLStreamWriterTest
  * @run testng/othervm stream.XMLStreamWriterTest.XMLStreamWriterTest
@@ -42,6 +50,48 @@
  */
 @Listeners({jaxp.library.BasePolicy.class})
 public class XMLStreamWriterTest {
+    /**
+     * @bug 8139584
+     * Verifies that the resulting XML contains the standalone setting.
+     */
+    @Test
+    public void testCreateStartDocument() throws XMLStreamException {
+
+        StringWriter stringWriter = new StringWriter();
+        XMLOutputFactory out = XMLOutputFactory.newInstance();
+        XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+
+        XMLEventWriter eventWriter = out.createXMLEventWriter(stringWriter);
+
+        XMLEvent event = eventFactory.createStartDocument("iso-8859-15", "1.0", true);
+        eventWriter.add(event);
+        eventWriter.flush();
+        Assert.assertTrue(stringWriter.toString().contains("encoding=\"iso-8859-15\""));
+        Assert.assertTrue(stringWriter.toString().contains("version=\"1.0\""));
+        Assert.assertTrue(stringWriter.toString().contains("standalone=\"yes\""));
+    }
+
+    /**
+     * @bug 8139584
+     * Verifies that the resulting XML contains the standalone setting.
+     */
+    @Test
+    public void testCreateStartDocument_DOMWriter()
+            throws ParserConfigurationException, XMLStreamException {
+
+        XMLOutputFactory xof = XMLOutputFactory.newInstance();
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        DocumentBuilder db = dbf.newDocumentBuilder();
+        Document doc = db.newDocument();
+        XMLEventWriter eventWriter = xof.createXMLEventWriter(new DOMResult(doc));
+        XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+        XMLEvent event = eventFactory.createStartDocument("iso-8859-15", "1.0", true);
+        eventWriter.add(event);
+        eventWriter.flush();
+        Assert.assertEquals(doc.getXmlEncoding(), "iso-8859-15");
+        Assert.assertEquals(doc.getXmlVersion(), "1.0");
+        Assert.assertTrue(doc.getXmlStandalone());
+    }
 
     /**
      * Test of main method, of class TestXMLStreamWriter.