1 /*
   2  * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package dom.ls;
  25 
  26 import java.io.IOException;
  27 import java.io.OutputStream;
  28 import java.io.StringReader;
  29 import java.io.Writer;
  30 
  31 import javax.xml.parsers.DocumentBuilder;
  32 import javax.xml.parsers.DocumentBuilderFactory;
  33 import javax.xml.parsers.ParserConfigurationException;
  34 
  35 import org.testng.Assert;
  36 import org.testng.annotations.Test;
  37 import org.w3c.dom.DOMConfiguration;
  38 import org.w3c.dom.DOMError;
  39 import org.w3c.dom.DOMErrorHandler;
  40 import org.w3c.dom.DOMImplementation;
  41 import org.w3c.dom.Document;
  42 import org.w3c.dom.ls.DOMImplementationLS;
  43 import org.w3c.dom.ls.LSException;
  44 import org.w3c.dom.ls.LSOutput;
  45 import org.w3c.dom.ls.LSSerializer;
  46 import org.xml.sax.InputSource;
  47 import org.xml.sax.SAXException;
  48 
  49 
  50 /*
  51  * @bug 6439439 8080906
  52  * @summary Test LSSerializer.
  53  */
  54 public class LSSerializerTest {
  55     private static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
  56 
  57     class DOMErrorHandlerImpl implements DOMErrorHandler {
  58 
  59         boolean NoOutputSpecifiedErrorReceived = false;
  60 
  61         public boolean handleError(final DOMError error) {
  62             // consume "no-output-specified" errors
  63             if ("no-output-specified".equalsIgnoreCase(error.getType())) {
  64                 NoOutputSpecifiedErrorReceived = true;
  65                 return true;
  66             }
  67 
  68             // unexpected error
  69             Assert.fail("Unexpected Error Type: " + error.getType() + " @ (" + error.getLocation().getLineNumber() + ", "
  70                     + error.getLocation().getColumnNumber() + ")" + ", " + error.getMessage());
  71 
  72             return false;
  73         }
  74     }
  75 
  76     class Output implements LSOutput {
  77         public OutputStream getByteStream() {
  78             return null;
  79         }
  80 
  81         public void setByteStream(final OutputStream byteStream) {
  82         }
  83 
  84         public Writer getCharacterStream() {
  85             return null;
  86         }
  87 
  88         public void setCharacterStream(final Writer characterStream) {
  89         }
  90 
  91         public String getSystemId() {
  92             return null;
  93         }
  94 
  95         public void setSystemId(final String systemId) {
  96         }
  97 
  98         public String getEncoding() {
  99             return "UTF8";
 100         }
 101 
 102         public void setEncoding(final String encoding) {
 103         }
 104     }
 105 
 106     /*
 107      * @bug 8080906
 108      */
 109     @Test
 110     public void testDefaultLSSerializer() throws Exception {
 111         DOMImplementationLS domImpl = (DOMImplementationLS) DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 112         LSSerializer lsSerializer = domImpl.createLSSerializer();
 113         Assert.assertTrue(lsSerializer.getClass().getName().endsWith("dom3.LSSerializerImpl"));
 114     }
 115 
 116     @Test
 117     public void testDOMErrorHandler() {
 118 
 119         final String XML_DOCUMENT = "<?xml version=\"1.0\"?>" + "<hello>" + "world" + "</hello>";
 120 
 121         StringReader stringReader = new StringReader(XML_DOCUMENT);
 122         InputSource inputSource = new InputSource(stringReader);
 123         Document doc = null;
 124         try {
 125             DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 126             // LSSerializer defaults to Namespace processing
 127             // so parsing must also
 128             documentBuilderFactory.setNamespaceAware(true);
 129             DocumentBuilder parser = documentBuilderFactory.newDocumentBuilder();
 130             doc = parser.parse(inputSource);
 131 
 132         } catch (Throwable e) {
 133             e.printStackTrace();
 134             Assert.fail(e.toString());
 135         }
 136 
 137         DOMImplementation impl = doc.getImplementation();
 138         DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0");
 139         LSSerializer writer = implLS.createLSSerializer();
 140 
 141         System.out.println("Serializer is: " + implLS.getClass().getName() + " " + implLS);
 142 
 143         DOMErrorHandlerImpl eh = new DOMErrorHandlerImpl();
 144         writer.getDomConfig().setParameter("error-handler", eh);
 145 
 146         boolean serialized = false;
 147         try {
 148             serialized = writer.write(doc, new Output());
 149 
 150             // unexpected success
 151             Assert.fail("Serialized without raising an LSException due to " + "'no-output-specified'.");
 152         } catch (LSException lsException) {
 153             // expected exception
 154             System.out.println("Expected LSException: " + lsException.toString());
 155             // continue processing
 156         }
 157 
 158         Assert.assertFalse(serialized, "Expected writer.write(doc, new Output()) == false");
 159 
 160         Assert.assertTrue(eh.NoOutputSpecifiedErrorReceived, "'no-output-specified' error was expected");
 161     }
 162 
 163     @Test
 164     public void testFormatPrettyPrint() {
 165 
 166         final String XML_DOCUMENT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n" + "<hello>" + "world" + "<child><children/><children/></child>"
 167                 + "</hello>";
 168         /**JDK-8035467
 169          * no newline in default output
 170          */
 171         final String XML_DOCUMENT_DEFAULT_PRINT =
 172                 "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
 173                 + "<hello>"
 174                 + "world"
 175                 + "<child><children/><children/></child>"
 176                 + "</hello>";
 177 
 178         final String XML_DOCUMENT_PRETTY_PRINT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + "<hello>" + "world" + "<child>" + "\n" + "        "
 179                 + "<children/>" + "\n" + "        " + "<children/>" + "\n" + "    " + "</child>" + "\n" + "</hello>" + "\n";
 180 
 181         // it all begins with a Document
 182         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 183         DocumentBuilder documentBuilder = null;
 184         try {
 185             documentBuilder = documentBuilderFactory.newDocumentBuilder();
 186         } catch (ParserConfigurationException parserConfigurationException) {
 187             parserConfigurationException.printStackTrace();
 188             Assert.fail(parserConfigurationException.toString());
 189         }
 190         Document document = null;
 191 
 192         StringReader stringReader = new StringReader(XML_DOCUMENT);
 193         InputSource inputSource = new InputSource(stringReader);
 194         try {
 195             document = documentBuilder.parse(inputSource);
 196         } catch (SAXException saxException) {
 197             saxException.printStackTrace();
 198             Assert.fail(saxException.toString());
 199         } catch (IOException ioException) {
 200             ioException.printStackTrace();
 201             Assert.fail(ioException.toString());
 202         }
 203 
 204         // query DOM Interfaces to get to a LSSerializer
 205         DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
 206         DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
 207         LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
 208 
 209         System.out.println("Serializer is: " + lsSerializer.getClass().getName() + " " + lsSerializer);
 210 
 211         // get configuration
 212         DOMConfiguration domConfiguration = lsSerializer.getDomConfig();
 213 
 214         // query current configuration
 215         Boolean defaultFormatPrettyPrint = (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT);
 216         Boolean canSetFormatPrettyPrintFalse = (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE);
 217         Boolean canSetFormatPrettyPrintTrue = (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
 218 
 219         System.out.println(DOM_FORMAT_PRETTY_PRINT + " default/can set false/can set true = " + defaultFormatPrettyPrint + "/"
 220                 + canSetFormatPrettyPrintFalse + "/" + canSetFormatPrettyPrintTrue);
 221 
 222         // test values
 223         Assert.assertEquals(defaultFormatPrettyPrint, Boolean.FALSE, "Default value of " + DOM_FORMAT_PRETTY_PRINT + " should be " + Boolean.FALSE);
 224 
 225         Assert.assertEquals(canSetFormatPrettyPrintFalse, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.FALSE + " should be "
 226                 + Boolean.TRUE);
 227 
 228         Assert.assertEquals(canSetFormatPrettyPrintTrue, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.TRUE + " should be "
 229                 + Boolean.TRUE);
 230 
 231         // get default serialization
 232         String prettyPrintDefault = lsSerializer.writeToString(document);
 233         System.out.println("(default) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 234                 + ": \n\"" + prettyPrintDefault + "\"");
 235 
 236         Assert.assertEquals(XML_DOCUMENT_DEFAULT_PRINT, prettyPrintDefault, "Invalid serialization with default value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 237                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 238 
 239         // configure LSSerializer to not format-pretty-print
 240         domConfiguration.setParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE);
 241         String prettyPrintFalse = lsSerializer.writeToString(document);
 242         System.out.println("(FALSE) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 243                 + ": \n\"" + prettyPrintFalse + "\"");
 244 
 245         Assert.assertEquals(XML_DOCUMENT_DEFAULT_PRINT, prettyPrintFalse, "Invalid serialization with FALSE value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 246                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 247 
 248         // configure LSSerializer to format-pretty-print
 249         domConfiguration.setParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
 250         String prettyPrintTrue = lsSerializer.writeToString(document);
 251         System.out.println("(TRUE) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 252                 + ": \n\"" + prettyPrintTrue + "\"");
 253 
 254         Assert.assertEquals(XML_DOCUMENT_PRETTY_PRINT, prettyPrintTrue, "Invalid serialization with TRUE value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 255                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 256     }
 257 
 258     @Test
 259     public void testXML11() {
 260 
 261         /**
 262          * XML 1.1 document to parse.
 263          */
 264         final String XML11_DOCUMENT = "<?xml version=\"1.1\" encoding=\"UTF-16\"?>\n" + "<hello>" + "world" + "<child><children/><children/></child>"
 265                 + "</hello>";
 266 
 267         /**JDK-8035467
 268          * no newline in default output
 269          */
 270         final String XML11_DOCUMENT_OUTPUT =
 271                 "<?xml version=\"1.1\" encoding=\"UTF-16\"?>"
 272                 + "<hello>"
 273                 + "world"
 274                 + "<child><children/><children/></child>"
 275                 + "</hello>";
 276 
 277         // it all begins with a Document
 278         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 279         DocumentBuilder documentBuilder = null;
 280         try {
 281             documentBuilder = documentBuilderFactory.newDocumentBuilder();
 282         } catch (ParserConfigurationException parserConfigurationException) {
 283             parserConfigurationException.printStackTrace();
 284             Assert.fail(parserConfigurationException.toString());
 285         }
 286         Document document = null;
 287 
 288         StringReader stringReader = new StringReader(XML11_DOCUMENT);
 289         InputSource inputSource = new InputSource(stringReader);
 290         try {
 291             document = documentBuilder.parse(inputSource);
 292         } catch (SAXException saxException) {
 293             saxException.printStackTrace();
 294             Assert.fail(saxException.toString());
 295         } catch (IOException ioException) {
 296             ioException.printStackTrace();
 297             Assert.fail(ioException.toString());
 298         }
 299 
 300         // query DOM Interfaces to get to a LSSerializer
 301         DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
 302         DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
 303         LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
 304 
 305         System.out.println("Serializer is: " + lsSerializer.getClass().getName() + " " + lsSerializer);
 306 
 307         // get default serialization
 308         String defaultSerialization = lsSerializer.writeToString(document);
 309 
 310         System.out.println("XML 1.1 serialization = \"" + defaultSerialization + "\"");
 311 
 312         // output should == input
 313         Assert.assertEquals(XML11_DOCUMENT_OUTPUT, defaultSerialization, "Invalid serialization of XML 1.1 document: ");
 314     }
 315 }