1 /*
   2  * Copyright (c) 2014, 2016, 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.Listeners;
  37 import org.testng.annotations.Test;
  38 import org.w3c.dom.DOMConfiguration;
  39 import org.w3c.dom.DOMError;
  40 import org.w3c.dom.DOMErrorHandler;
  41 import org.w3c.dom.DOMImplementation;
  42 import org.w3c.dom.Document;
  43 import org.w3c.dom.ls.DOMImplementationLS;
  44 import org.w3c.dom.ls.LSException;
  45 import org.w3c.dom.ls.LSOutput;
  46 import org.w3c.dom.ls.LSSerializer;
  47 import org.xml.sax.InputSource;
  48 import org.xml.sax.SAXException;
  49 
  50 
  51 /*
  52  * @bug 6439439 8080906
  53  * @summary Test LSSerializer.
  54  */
  55 @Listeners({jaxp.library.BasePolicy.class})
  56 public class LSSerializerTest {
  57     private static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
  58 
  59     class DOMErrorHandlerImpl implements DOMErrorHandler {
  60 
  61         boolean NoOutputSpecifiedErrorReceived = false;
  62 
  63         public boolean handleError(final DOMError error) {
  64             // consume "no-output-specified" errors
  65             if ("no-output-specified".equalsIgnoreCase(error.getType())) {
  66                 NoOutputSpecifiedErrorReceived = true;
  67                 return true;
  68             }
  69 
  70             // unexpected error
  71             Assert.fail("Unexpected Error Type: " + error.getType() + " @ (" + error.getLocation().getLineNumber() + ", "
  72                     + error.getLocation().getColumnNumber() + ")" + ", " + error.getMessage());
  73 
  74             return false;
  75         }
  76     }
  77 
  78     class Output implements LSOutput {
  79         public OutputStream getByteStream() {
  80             return null;
  81         }
  82 
  83         public void setByteStream(final OutputStream byteStream) {
  84         }
  85 
  86         public Writer getCharacterStream() {
  87             return null;
  88         }
  89 
  90         public void setCharacterStream(final Writer characterStream) {
  91         }
  92 
  93         public String getSystemId() {
  94             return null;
  95         }
  96 
  97         public void setSystemId(final String systemId) {
  98         }
  99 
 100         public String getEncoding() {
 101             return "UTF8";
 102         }
 103 
 104         public void setEncoding(final String encoding) {
 105         }
 106     }
 107 
 108     /*
 109      * @bug 8080906
 110      */
 111     @Test
 112     public void testDefaultLSSerializer() throws Exception {
 113         DOMImplementationLS domImpl = (DOMImplementationLS) DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 114         LSSerializer lsSerializer = domImpl.createLSSerializer();
 115         Assert.assertTrue(lsSerializer.getClass().getName().endsWith("dom3.LSSerializerImpl"));
 116     }
 117 
 118     @Test
 119     public void testDOMErrorHandler() {
 120 
 121         final String XML_DOCUMENT = "<?xml version=\"1.0\"?>" + "<hello>" + "world" + "</hello>";
 122 
 123         StringReader stringReader = new StringReader(XML_DOCUMENT);
 124         InputSource inputSource = new InputSource(stringReader);
 125         Document doc = null;
 126         try {
 127             DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 128             // LSSerializer defaults to Namespace processing
 129             // so parsing must also
 130             documentBuilderFactory.setNamespaceAware(true);
 131             DocumentBuilder parser = documentBuilderFactory.newDocumentBuilder();
 132             doc = parser.parse(inputSource);
 133 
 134         } catch (Throwable e) {
 135             e.printStackTrace();
 136             Assert.fail(e.toString());
 137         }
 138 
 139         DOMImplementation impl = doc.getImplementation();
 140         DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0");
 141         LSSerializer writer = implLS.createLSSerializer();
 142 
 143         System.out.println("Serializer is: " + implLS.getClass().getName() + " " + implLS);
 144 
 145         DOMErrorHandlerImpl eh = new DOMErrorHandlerImpl();
 146         writer.getDomConfig().setParameter("error-handler", eh);
 147 
 148         boolean serialized = false;
 149         try {
 150             serialized = writer.write(doc, new Output());
 151 
 152             // unexpected success
 153             Assert.fail("Serialized without raising an LSException due to " + "'no-output-specified'.");
 154         } catch (LSException lsException) {
 155             // expected exception
 156             System.out.println("Expected LSException: " + lsException.toString());
 157             // continue processing
 158         }
 159 
 160         Assert.assertFalse(serialized, "Expected writer.write(doc, new Output()) == false");
 161 
 162         Assert.assertTrue(eh.NoOutputSpecifiedErrorReceived, "'no-output-specified' error was expected");
 163     }
 164 
 165     @Test
 166     public void testFormatPrettyPrint() {
 167 
 168         final String XML_DOCUMENT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n" + "<hello>" + "world" + "<child><children/><children/></child>"
 169                 + "</hello>";
 170         /**JDK-8035467
 171          * no newline in default output
 172          */
 173         final String XML_DOCUMENT_DEFAULT_PRINT =
 174                 "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
 175                 + "<hello>"
 176                 + "world"
 177                 + "<child><children/><children/></child>"
 178                 + "</hello>";
 179 
 180         final String XML_DOCUMENT_PRETTY_PRINT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + "<hello>" + "world" + "<child>" + "\n" + "        "
 181                 + "<children/>" + "\n" + "        " + "<children/>" + "\n" + "    " + "</child>" + "\n" + "</hello>" + "\n";
 182 
 183         // it all begins with a Document
 184         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 185         DocumentBuilder documentBuilder = null;
 186         try {
 187             documentBuilder = documentBuilderFactory.newDocumentBuilder();
 188         } catch (ParserConfigurationException parserConfigurationException) {
 189             parserConfigurationException.printStackTrace();
 190             Assert.fail(parserConfigurationException.toString());
 191         }
 192         Document document = null;
 193 
 194         StringReader stringReader = new StringReader(XML_DOCUMENT);
 195         InputSource inputSource = new InputSource(stringReader);
 196         try {
 197             document = documentBuilder.parse(inputSource);
 198         } catch (SAXException saxException) {
 199             saxException.printStackTrace();
 200             Assert.fail(saxException.toString());
 201         } catch (IOException ioException) {
 202             ioException.printStackTrace();
 203             Assert.fail(ioException.toString());
 204         }
 205 
 206         // query DOM Interfaces to get to a LSSerializer
 207         DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
 208         DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
 209         LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
 210 
 211         System.out.println("Serializer is: " + lsSerializer.getClass().getName() + " " + lsSerializer);
 212 
 213         // get configuration
 214         DOMConfiguration domConfiguration = lsSerializer.getDomConfig();
 215 
 216         // query current configuration
 217         Boolean defaultFormatPrettyPrint = (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT);
 218         Boolean canSetFormatPrettyPrintFalse = (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE);
 219         Boolean canSetFormatPrettyPrintTrue = (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
 220 
 221         System.out.println(DOM_FORMAT_PRETTY_PRINT + " default/can set false/can set true = " + defaultFormatPrettyPrint + "/"
 222                 + canSetFormatPrettyPrintFalse + "/" + canSetFormatPrettyPrintTrue);
 223 
 224         // test values
 225         Assert.assertEquals(defaultFormatPrettyPrint, Boolean.FALSE, "Default value of " + DOM_FORMAT_PRETTY_PRINT + " should be " + Boolean.FALSE);
 226 
 227         Assert.assertEquals(canSetFormatPrettyPrintFalse, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.FALSE + " should be "
 228                 + Boolean.TRUE);
 229 
 230         Assert.assertEquals(canSetFormatPrettyPrintTrue, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.TRUE + " should be "
 231                 + Boolean.TRUE);
 232 
 233         // get default serialization
 234         String prettyPrintDefault = lsSerializer.writeToString(document);
 235         System.out.println("(default) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 236                 + ": \n\"" + prettyPrintDefault + "\"");
 237 
 238         Assert.assertEquals(XML_DOCUMENT_DEFAULT_PRINT, prettyPrintDefault, "Invalid serialization with default value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 239                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 240 
 241         // configure LSSerializer to not format-pretty-print
 242         domConfiguration.setParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE);
 243         String prettyPrintFalse = lsSerializer.writeToString(document);
 244         System.out.println("(FALSE) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 245                 + ": \n\"" + prettyPrintFalse + "\"");
 246 
 247         Assert.assertEquals(XML_DOCUMENT_DEFAULT_PRINT, prettyPrintFalse, "Invalid serialization with FALSE value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 248                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 249 
 250         // configure LSSerializer to format-pretty-print
 251         domConfiguration.setParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE);
 252         String prettyPrintTrue = lsSerializer.writeToString(document);
 253         System.out.println("(TRUE) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)
 254                 + ": \n\"" + prettyPrintTrue + "\"");
 255 
 256         Assert.assertEquals(XML_DOCUMENT_PRETTY_PRINT, prettyPrintTrue, "Invalid serialization with TRUE value, " + DOM_FORMAT_PRETTY_PRINT + "=="
 257                 + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
 258     }
 259 
 260     @Test
 261     public void testXML11() {
 262 
 263         /**
 264          * XML 1.1 document to parse.
 265          */
 266         final String XML11_DOCUMENT = "<?xml version=\"1.1\" encoding=\"UTF-16\"?>\n" + "<hello>" + "world" + "<child><children/><children/></child>"
 267                 + "</hello>";
 268 
 269         /**JDK-8035467
 270          * no newline in default output
 271          */
 272         final String XML11_DOCUMENT_OUTPUT =
 273                 "<?xml version=\"1.1\" encoding=\"UTF-16\"?>"
 274                 + "<hello>"
 275                 + "world"
 276                 + "<child><children/><children/></child>"
 277                 + "</hello>";
 278 
 279         // it all begins with a Document
 280         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 281         DocumentBuilder documentBuilder = null;
 282         try {
 283             documentBuilder = documentBuilderFactory.newDocumentBuilder();
 284         } catch (ParserConfigurationException parserConfigurationException) {
 285             parserConfigurationException.printStackTrace();
 286             Assert.fail(parserConfigurationException.toString());
 287         }
 288         Document document = null;
 289 
 290         StringReader stringReader = new StringReader(XML11_DOCUMENT);
 291         InputSource inputSource = new InputSource(stringReader);
 292         try {
 293             document = documentBuilder.parse(inputSource);
 294         } catch (SAXException saxException) {
 295             saxException.printStackTrace();
 296             Assert.fail(saxException.toString());
 297         } catch (IOException ioException) {
 298             ioException.printStackTrace();
 299             Assert.fail(ioException.toString());
 300         }
 301 
 302         // query DOM Interfaces to get to a LSSerializer
 303         DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
 304         DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
 305         LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
 306 
 307         System.out.println("Serializer is: " + lsSerializer.getClass().getName() + " " + lsSerializer);
 308 
 309         // get default serialization
 310         String defaultSerialization = lsSerializer.writeToString(document);
 311 
 312         System.out.println("XML 1.1 serialization = \"" + defaultSerialization + "\"");
 313 
 314         // output should == input
 315         Assert.assertEquals(XML11_DOCUMENT_OUTPUT, defaultSerialization, "Invalid serialization of XML 1.1 document: ");
 316     }
 317 }