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 package dom;
  24 
  25 import java.io.IOException;
  26 import java.io.StringReader;
  27 import java.net.URISyntaxException;
  28 
  29 import javax.xml.XMLConstants;
  30 import javax.xml.parsers.DocumentBuilder;
  31 import javax.xml.parsers.DocumentBuilderFactory;
  32 import javax.xml.parsers.FactoryConfigurationError;
  33 import javax.xml.parsers.ParserConfigurationException;
  34 
  35 import org.testng.Assert;
  36 import org.testng.annotations.Test;
  37 import org.w3c.dom.Attr;
  38 import org.w3c.dom.CDATASection;
  39 import org.w3c.dom.Comment;
  40 import org.w3c.dom.DOMConfiguration;
  41 import org.w3c.dom.DOMError;
  42 import org.w3c.dom.DOMErrorHandler;
  43 import org.w3c.dom.DOMException;
  44 import org.w3c.dom.DOMImplementation;
  45 import org.w3c.dom.Document;
  46 import org.w3c.dom.Element;
  47 import org.w3c.dom.Entity;
  48 import org.w3c.dom.NamedNodeMap;
  49 import org.w3c.dom.Node;
  50 import org.w3c.dom.ProcessingInstruction;
  51 import org.w3c.dom.Text;
  52 import org.w3c.dom.ls.DOMImplementationLS;
  53 import org.w3c.dom.ls.LSInput;
  54 import org.w3c.dom.ls.LSParser;
  55 import org.xml.sax.InputSource;
  56 import org.xml.sax.SAXException;
  57 
  58 /*
  59  * @summary Test DOMConfiguration for supported properties.
  60  */
  61 public class DOMConfigurationTest {
  62 
  63     static class TestHandler implements DOMErrorHandler {
  64         private String warning;
  65         private String error;
  66         private String fatalError;
  67 
  68         public String getError() {
  69             return error;
  70         }
  71 
  72         public String getFatalError() {
  73             return fatalError;
  74         }
  75 
  76         public String getWarning() {
  77             return warning;
  78         }
  79 
  80         public boolean handleError(DOMError error) {
  81             if (error.getSeverity() == DOMError.SEVERITY_ERROR) {
  82                 this.error = "" + error.getMessage();
  83                 return false;
  84             }
  85             if (error.getSeverity() == DOMError.SEVERITY_FATAL_ERROR) {
  86                 this.fatalError = "" + error.getMessage();
  87                 return false;
  88             }
  89             this.warning = "" + error.getMessage();
  90             return true; // warning
  91         }
  92     }
  93 
  94     static class TestFailureHandler implements DOMErrorHandler {
  95         public boolean handleError(DOMError error) {
  96             if (error.getSeverity() == DOMError.SEVERITY_ERROR) {
  97                 Assert.fail("Error: " + error.getMessage());
  98             }
  99             if (error.getSeverity() == DOMError.SEVERITY_FATAL_ERROR) {
 100                 Assert.fail("Fatal error: " + error.getMessage());
 101             }
 102             return true; // warning
 103         }
 104     }
 105 
 106     void setHandler(Document doc) {
 107         doc.getDomConfig().setParameter("error-handler", new TestFailureHandler());
 108     }
 109 
 110     static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
 111 
 112     static final String SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
 113 
 114     static final String XMLNS = "http://www.w3.org/2000/xmlns/";
 115 
 116     static Document loadDocument(String schemaURL, String instanceText) {
 117         Document document = null;
 118         try {
 119             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 120             dbf.setNamespaceAware(true);
 121             dbf.setValidating(true);
 122             if (schemaURL != null) {
 123                 dbf.setAttribute(SCHEMA_LANGUAGE, XMLConstants.W3C_XML_SCHEMA_NS_URI);
 124                 dbf.setAttribute(SCHEMA_SOURCE, schemaURL);
 125             }
 126             DocumentBuilder parser = dbf.newDocumentBuilder();
 127 
 128             InputSource inSource = new InputSource(new StringReader(instanceText));
 129             inSource.setSystemId("doc.xml");
 130             document = parser.parse(inSource);
 131         } catch (ParserConfigurationException e) {
 132             Assert.fail(e.toString());
 133         } catch (IOException e) {
 134             Assert.fail(e.toString());
 135         } catch (SAXException e) {
 136             Assert.fail(e.toString());
 137         }
 138 
 139         return document;
 140     }
 141 
 142     static final String test_xml = "<?xml version=\"1.0\"?>\n" + "<test:root xmlns:test=\"test\" \n"
 143             + "           xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" + ">&#x9;&#xA;&#xD; 1 </test:root>\n";
 144 
 145     static final String test1_xml = "<?xml version=\"1.0\"?>\n" + "<!DOCTYPE root [\n" + "    <!ELEMENT root ANY>\n" + "    <!ENTITY x \"X\">\n" + "]>\n"
 146             + "<root/>\n";
 147 
 148     static final String test2_xml = "<?xml version=\"1.0\"?>\n" + "<!DOCTYPE root [\n" + "    <!ELEMENT root ANY>\n"
 149             + "    <!ATTLIST root attr CDATA #REQUIRED>\n" + "    <!ENTITY x \"<\">\n" + "]>\n" + "<root attr=\"x\"/>\n";
 150 
 151     static final String test3_xml = "<?xml version=\"1.0\"?>\n" + "<!DOCTYPE root [\n" + "    <!ELEMENT root (elem*)>\n" + "    <!ELEMENT elem EMPTY>\n"
 152             + "]>\n" + "<root/>\n";
 153 
 154     static String test1_xsd_url;
 155     static {
 156         try {
 157             test1_xsd_url = DOMConfigurationTest.class.getResource("DOMConfigurationTest.xsd").toURI().toString();
 158         } catch (URISyntaxException uriSyntaxException) {
 159             Assert.fail(uriSyntaxException.toString());
 160         }
 161     }
 162 
 163     /**
 164      * Equivalence class partitioning with state and input values orientation
 165      * for public void setParameter(String name, Object value) throws
 166      * DOMException, <br>
 167      * <b>pre-conditions</b>: the doc contains two subsequent processing
 168      * instrictions, <br>
 169      * <b>name</b>: canonical-form <br>
 170      * <b>value</b>: true. <br>
 171      * <b>Expected results</b>: the subsequent processing instrictions are
 172      * separated with a single line break
 173      */
 174     @Test
 175     public void testCanonicalForm001() {
 176         DOMImplementation domImpl = null;
 177         try {
 178             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 179         } catch (ParserConfigurationException pce) {
 180             Assert.fail(pce.toString());
 181         } catch (FactoryConfigurationError fce) {
 182             Assert.fail(fce.toString());
 183         }
 184 
 185         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 186 
 187         DOMConfiguration config = doc.getDomConfig();
 188 
 189         Element root = doc.getDocumentElement();
 190         ProcessingInstruction pi1 = doc.createProcessingInstruction("target1", "data1");
 191         ProcessingInstruction pi2 = doc.createProcessingInstruction("target2", "data2");
 192 
 193         root.appendChild(pi1);
 194         root.appendChild(pi2);
 195 
 196         if (!config.canSetParameter("canonical-form", Boolean.TRUE)) {
 197             System.out.println("OK, setting 'canonical-form' to true is not supported");
 198             return;
 199         }
 200 
 201         config.setParameter("canonical-form", Boolean.TRUE);
 202         setHandler(doc);
 203         doc.normalizeDocument();
 204 
 205         Node child1 = root.getFirstChild();
 206         Node child2 = child1.getNextSibling();
 207 
 208         if (child2.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
 209             Assert.fail("the second child is expected to be a" + "single line break, returned: " + child2);
 210         }
 211 
 212         // return Status.passed("OK");
 213     }
 214 
 215     /**
 216      * Equivalence class partitioning with state and input values orientation
 217      * for public void setParameter(String name, Object value) throws
 218      * DOMException, <br>
 219      * <b>pre-conditions</b>: the parameters "namespaces",
 220      * "namespace-declarations", "well-formed", "element-content-whitespace" are
 221      * set to false if possible; the parameters "entities",
 222      * "normalize-characters", "cdata-sections" are set to true if possible, <br>
 223      * <b>name</b>: canonical-form <br>
 224      * <b>value</b>: true. <br>
 225      * <b>Expected results</b>: the parameters "namespaces",
 226      * "namespace-declarations", "well-formed", "element-content-whitespace" are
 227      * set to true; the parameters "entities", "normalize-characters",
 228      * "cdata-sections" are set to false
 229      */
 230     @Test
 231     public void testCanonicalForm002() {
 232         Object[][] params = { { "namespaces", Boolean.TRUE }, { "namespace-declarations", Boolean.TRUE }, { "well-formed", Boolean.TRUE },
 233                 { "element-content-whitespace", Boolean.TRUE },
 234 
 235                 { "entities", Boolean.FALSE }, { "normalize-characters", Boolean.FALSE }, { "cdata-sections", Boolean.FALSE }, };
 236 
 237         DOMImplementation domImpl = null;
 238         try {
 239             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 240         } catch (ParserConfigurationException pce) {
 241             Assert.fail(pce.toString());
 242         } catch (FactoryConfigurationError fce) {
 243             Assert.fail(fce.toString());
 244         }
 245 
 246         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 247 
 248         DOMConfiguration config = doc.getDomConfig();
 249 
 250         if (!config.canSetParameter("canonical-form", Boolean.TRUE)) {
 251             System.out.println("OK, setting 'canonical-form' to true is not supported");
 252             return;
 253         }
 254 
 255         for (int i = params.length; --i >= 0;) {
 256             Boolean reset = params[i][1].equals(Boolean.TRUE) ? Boolean.FALSE : Boolean.TRUE;
 257             if (config.canSetParameter(params[i][0].toString(), reset)) {
 258                 config.setParameter(params[i][0].toString(), reset);
 259             }
 260         }
 261 
 262         config.setParameter("canonical-form", Boolean.TRUE);
 263 
 264         StringBuffer result = new StringBuffer();
 265 
 266         for (int i = params.length; --i >= 0;) {
 267             Object param = config.getParameter(params[i][0].toString());
 268             if (!params[i][1].equals(param)) {
 269                 result.append("; the parameter \'" + params[i][0] + "\' is set to " + param + ", expected: " + params[i][1]);
 270             }
 271         }
 272 
 273         if (result.length() > 0) {
 274             Assert.fail(result.toString().substring(2));
 275         }
 276 
 277         return; // Status.passed("OK");
 278     }
 279 
 280     /**
 281      * Equivalence class partitioning with state and input values orientation
 282      * for public void setParameter(String name, Object value) throws
 283      * DOMException, <br>
 284      * <b>pre-conditions</b>: the doc's root element contains superfluous
 285      * namespace declarations, <br>
 286      * <b>name</b>: canonical-form <br>
 287      * <b>value</b>: true. <br>
 288      * <b>Expected results</b>: the superfluous namespace declarations are
 289      * removed
 290      */
 291     @Test
 292     public void testCanonicalForm003() {
 293         DOMImplementation domImpl = null;
 294         try {
 295             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 296         } catch (ParserConfigurationException pce) {
 297             Assert.fail(pce.toString());
 298         } catch (FactoryConfigurationError fce) {
 299             Assert.fail(fce.toString());
 300         }
 301 
 302         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 303 
 304         DOMConfiguration config = doc.getDomConfig();
 305 
 306         Element root = doc.getDocumentElement();
 307         String XMLNS = "http://www.w3.org/2000/xmlns/";
 308         root.setAttributeNS(XMLNS, "xmlns:extra1", "ExtraNS1");
 309         root.setAttributeNS(XMLNS, "xmlns:extra2", "ExtraNS2");
 310 
 311         if (!config.canSetParameter("canonical-form", Boolean.TRUE)) {
 312             System.out.println("OK, setting 'canonical-form' to true is not supported");
 313             return;
 314         }
 315         config.setParameter("canonical-form", Boolean.TRUE);
 316         setHandler(doc);
 317         doc.normalizeDocument();
 318 
 319         String xmlns2 = root.getAttributeNS(XMLNS, "extra1");
 320         if (xmlns2 == null || xmlns2.length() != 0) {
 321             Assert.fail("superfluous namespace declarations is not removed: xmlns:extra2 = " + xmlns2);
 322         }
 323 
 324         return; // Status.passed("OK");
 325     }
 326 
 327     /**
 328      * Equivalence class partitioning with state and input values orientation
 329      * for public void setParameter(String name, Object value) throws
 330      * DOMException, <br>
 331      * <b>pre-conditions</b>: setting the "canonical-form" to true is supported, <br>
 332      * <b>name</b>: canonical-form <br>
 333      * <b>value</b>: true. <br>
 334      * <b>Expected results</b>: one of the following parameters is changed:
 335      * "namespaces", "namespace-declarations", "well-formed",
 336      * "element-content-whitespace", "entities", "normalize-characters",
 337      * "cdata-sections" then "canonical-form" becomes false
 338      */
 339     @Test
 340     public void testCanonicalForm004() {
 341         Object[][] params = { { "namespaces", Boolean.TRUE }, { "namespace-declarations", Boolean.TRUE }, { "well-formed", Boolean.TRUE },
 342                 { "element-content-whitespace", Boolean.TRUE },
 343 
 344                 { "entities", Boolean.FALSE }, { "normalize-characters", Boolean.FALSE }, { "cdata-sections", Boolean.FALSE }, };
 345 
 346         DOMImplementation domImpl = null;
 347         try {
 348             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 349         } catch (ParserConfigurationException pce) {
 350             Assert.fail(pce.toString());
 351         } catch (FactoryConfigurationError fce) {
 352             Assert.fail(fce.toString());
 353         }
 354 
 355         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 356 
 357         DOMConfiguration config = doc.getDomConfig();
 358 
 359         if (!config.canSetParameter("canonical-form", Boolean.TRUE)) {
 360             System.out.println("OK, setting 'canonical-form' to true is not supported");
 361             return;
 362         }
 363 
 364         StringBuffer result = new StringBuffer();
 365 
 366         for (int i = params.length; --i >= 0;) {
 367             config.setParameter("canonical-form", Boolean.TRUE);
 368             Boolean changedValue = (params[i][1].equals(Boolean.TRUE)) ? Boolean.FALSE : Boolean.TRUE;
 369             if (config.canSetParameter(params[i][0].toString(), changedValue)) {
 370                 config.setParameter(params[i][0].toString(), changedValue);
 371                 Object param = config.getParameter("canonical-form");
 372                 if (!Boolean.FALSE.equals(param)) {
 373                     result.append("; setting the parameter '" + params[i][0] + "' to " + changedValue + " does not change 'canonical-form' to false");
 374                 }
 375             }
 376         }
 377 
 378         if (result.length() > 0) {
 379             Assert.fail(result.toString().substring(2));
 380         }
 381 
 382         return; // Status.passed("OK");
 383     }
 384 
 385     /**
 386      * Equivalence class partitioning with state and input values orientation
 387      * for public void setParameter(String name, Object value) throws
 388      * DOMException, <br>
 389      * <b>pre-conditions</b>: the root element has one CDATASection followed by
 390      * one Text node, <br>
 391      * <b>name</b>: cdata-sections <br>
 392      * <b>value</b>: true. <br>
 393      * <b>Expected results</b>: the CDATASection is left intact
 394      */
 395     @Test
 396     public void testCdataSections001() {
 397         DOMImplementation domImpl = null;
 398         try {
 399             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 400         } catch (ParserConfigurationException pce) {
 401             Assert.fail(pce.toString());
 402         } catch (FactoryConfigurationError fce) {
 403             Assert.fail(fce.toString());
 404         }
 405 
 406         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 407 
 408         String cdataText = "CDATA CDATA CDATA";
 409         String textText = "text text text";
 410 
 411         CDATASection cdata = doc.createCDATASection(cdataText);
 412         Text text = doc.createTextNode(textText);
 413 
 414         DOMConfiguration config = doc.getDomConfig();
 415         config.setParameter("cdata-sections", Boolean.TRUE);
 416 
 417         Element root = doc.getDocumentElement();
 418         root.appendChild(cdata);
 419         root.appendChild(text);
 420 
 421         setHandler(doc);
 422         doc.normalizeDocument();
 423 
 424         Node returned = root.getFirstChild();
 425 
 426         if (returned.getNodeType() != Node.CDATA_SECTION_NODE) {
 427             Assert.fail("reurned: " + returned + ", expected: CDATASection");
 428         }
 429 
 430         return; // Status.passed("OK");
 431 
 432     }
 433 
 434     /**
 435      * Equivalence class partitioning with state and input values orientation
 436      * for public void setParameter(String name, Object value) throws
 437      * DOMException, <br>
 438      * <b>pre-conditions</b>: the root element has one CDATASection followed by
 439      * one Text node, <br>
 440      * <b>name</b>: cdata-sections <br>
 441      * <b>value</b>: false. <br>
 442      * <b>Expected results</b>: the root element has one Text node with text of
 443      * the CDATASection and the Text node
 444      */
 445     @Test
 446     public void testCdataSections002() {
 447         DOMImplementation domImpl = null;
 448         try {
 449             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 450         } catch (ParserConfigurationException pce) {
 451             Assert.fail(pce.toString());
 452         } catch (FactoryConfigurationError fce) {
 453             Assert.fail(fce.toString());
 454         }
 455 
 456         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 457 
 458         String cdataText = "CDATA CDATA CDATA";
 459         String textText = "text text text";
 460 
 461         CDATASection cdata = doc.createCDATASection(cdataText);
 462         Text text = doc.createTextNode(textText);
 463 
 464         DOMConfiguration config = doc.getDomConfig();
 465         config.setParameter("cdata-sections", Boolean.FALSE);
 466 
 467         Element root = doc.getDocumentElement();
 468         root.appendChild(cdata);
 469         root.appendChild(text);
 470 
 471         setHandler(doc);
 472         doc.normalizeDocument();
 473 
 474         Node returned = root.getFirstChild();
 475 
 476         if (returned.getNodeType() != Node.TEXT_NODE) {
 477             Assert.fail("reurned: " + returned + ", expected: TEXT_NODE");
 478         }
 479 
 480         String returnedText = returned.getNodeValue();
 481         if (!(cdataText + textText).equals(returnedText)) {
 482             Assert.fail("reurned: " + returnedText + ", expected: \"" + cdataText + textText + "\"");
 483         }
 484 
 485         return; // Status.passed("OK");
 486 
 487     }
 488 
 489     /**
 490      * Equivalence class partitioning with state and input values orientation
 491      * for public void setParameter(String name, Object value) throws
 492      * DOMException, <br>
 493      * <b>pre-conditions</b>: the root element has one Text node with not fully
 494      * normalized characters, the 'check-character-normalization' parameter set
 495      * to true, <br>
 496      * <b>name</b>: error-handler <br>
 497      * <b>value</b>: DOMErrorHandler. <br>
 498      * <b>Expected results</b>: LSParser calls the specified error handler
 499      */
 500     @Test
 501     public void testCheckCharNorm001() {
 502         DOMImplementation domImpl = null;
 503         try {
 504             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 505         } catch (ParserConfigurationException pce) {
 506             Assert.fail(pce.toString());
 507         } catch (FactoryConfigurationError fce) {
 508             Assert.fail(fce.toString());
 509         }
 510 
 511         DOMImplementationLS lsImpl = (DOMImplementationLS) domImpl.getFeature("LS", "3.0");
 512 
 513         if (lsImpl == null) {
 514             System.out.println("OK, the DOM implementation does not support the LS 3.0");
 515             return;
 516         }
 517 
 518         LSParser lsParser = lsImpl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
 519 
 520         DOMConfiguration config = lsParser.getDomConfig();
 521 
 522         if (!config.canSetParameter("check-character-normalization", Boolean.TRUE)) {
 523             System.out.println("OK, setting 'check-character-normalization' to true is not supported");
 524             return;
 525         }
 526 
 527         config.setParameter("check-character-normalization", Boolean.TRUE);
 528 
 529         TestHandler testHandler = new TestHandler();
 530         config.setParameter("error-handler", testHandler);
 531 
 532         LSInput lsInput = lsImpl.createLSInput();
 533         lsInput.setStringData("<root>\u0073\u0075\u0063\u0327\u006F\u006E</root>");
 534         Document doc = lsParser.parse(lsInput);
 535 
 536         if (null == testHandler.getError()) {
 537             Assert.fail("no error is reported, expected 'check-character-normalization-failure'");
 538 
 539         }
 540 
 541         return; // Status.passed("OK");
 542 
 543     }
 544 
 545     /**
 546      * Equivalence class partitioning with state and input values orientation
 547      * for public void setParameter(String name, Object value) throws
 548      * DOMException, <br>
 549      * <b>pre-conditions</b>: the root element contains a fully-normalized text, <br>
 550      * <b>name</b>: check-character-normalization <br>
 551      * <b>value</b>: false. <br>
 552      * <b>Expected results</b>: LSParser reports no errors
 553      */
 554     @Test
 555     public void testCheckCharNorm002() {
 556         DOMImplementation domImpl = null;
 557         try {
 558             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 559         } catch (ParserConfigurationException pce) {
 560             Assert.fail(pce.toString());
 561         } catch (FactoryConfigurationError fce) {
 562             Assert.fail(fce.toString());
 563         }
 564 
 565         DOMImplementationLS lsImpl = (DOMImplementationLS) domImpl.getFeature("LS", "3.0");
 566 
 567         if (lsImpl == null) {
 568             System.out.println("OK, the DOM implementation does not support the LS 3.0");
 569             return;
 570         }
 571 
 572         LSParser lsParser = lsImpl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
 573 
 574         DOMConfiguration config = lsParser.getDomConfig();
 575 
 576         if (!config.canSetParameter("check-character-normalization", Boolean.FALSE)) {
 577             Assert.fail("setting 'check-character-normalization' to false is not supported");
 578         }
 579 
 580         config.setParameter("check-character-normalization", Boolean.FALSE);
 581 
 582         TestHandler testHandler = new TestHandler();
 583         config.setParameter("error-handler", testHandler);
 584 
 585         LSInput lsInput = lsImpl.createLSInput();
 586         lsInput.setStringData("<root>fully-normalized</root>");
 587         Document doc = lsParser.parse(lsInput);
 588 
 589         if (null != testHandler.getError()) {
 590             Assert.fail("no error is expected, but reported: " + testHandler.getError());
 591 
 592         }
 593 
 594         return; // Status.passed("OK");
 595 
 596     }
 597 
 598     /**
 599      * Equivalence class partitioning with state and input values orientation
 600      * for public void setParameter(String name, Object value) throws
 601      * DOMException, <br>
 602      * <b>pre-conditions</b>: the root element has two Comment nodes, <br>
 603      * <b>name</b>: comments <br>
 604      * <b>value</b>: true. <br>
 605      * <b>Expected results</b>: the Comment nodes belong to the root element
 606      */
 607     @Test
 608     public void testComments001() {
 609         DOMImplementation domImpl = null;
 610         try {
 611             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 612         } catch (ParserConfigurationException pce) {
 613             Assert.fail(pce.toString());
 614         } catch (FactoryConfigurationError fce) {
 615             Assert.fail(fce.toString());
 616         }
 617 
 618         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 619 
 620         Comment comment1 = doc.createComment("comment1");
 621         Comment comment2 = doc.createComment("comment2");
 622 
 623         DOMConfiguration config = doc.getDomConfig();
 624         config.setParameter("comments", Boolean.TRUE);
 625 
 626         Element root = doc.getDocumentElement();
 627         root.appendChild(comment1);
 628         root.appendChild(comment2);
 629 
 630         setHandler(doc);
 631         doc.normalizeDocument();
 632 
 633         if (comment1.getParentNode() != root) {
 634             Assert.fail("comment1 is attached to " + comment1.getParentNode() + ", but expected to be a child of root");
 635         }
 636 
 637         if (comment2.getParentNode() != root) {
 638             Assert.fail("comment1 is attached to " + comment2.getParentNode() + ", but expected to be a child of root");
 639         }
 640 
 641         return; // Status.passed("OK");
 642 
 643     }
 644 
 645     /**
 646      * Equivalence class partitioning with state and input values orientation
 647      * for public void setParameter(String name, Object value) throws
 648      * DOMException, <br>
 649      * <b>pre-conditions</b>: the root element has two Comment nodes, <br>
 650      * <b>name</b>: comments <br>
 651      * <b>value</b>: false. <br>
 652      * <b>Expected results</b>: the root element has no children
 653      */
 654     @Test
 655     public void testComments002() {
 656         DOMImplementation domImpl = null;
 657         try {
 658             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 659         } catch (ParserConfigurationException pce) {
 660             Assert.fail(pce.toString());
 661         } catch (FactoryConfigurationError fce) {
 662             Assert.fail(fce.toString());
 663         }
 664 
 665         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 666 
 667         Comment comment1 = doc.createComment("comment1");
 668         Comment comment2 = doc.createComment("comment2");
 669 
 670         DOMConfiguration config = doc.getDomConfig();
 671         config.setParameter("comments", Boolean.FALSE);
 672 
 673         Element root = doc.getDocumentElement();
 674         root.appendChild(comment1);
 675         root.appendChild(comment2);
 676 
 677         doc.normalizeDocument();
 678 
 679         if (root.getFirstChild() != null) {
 680             Assert.fail("root has a child " + root.getFirstChild() + ", but expected to has none");
 681         }
 682 
 683         return; // Status.passed("OK");
 684 
 685     }
 686 
 687     /**
 688      * Equivalence class partitioning with state and input values orientation
 689      * for public void setParameter(String name, Object value) throws
 690      * DOMException, <br>
 691      * <b>pre-conditions</b>: the root element is declared as int and its value
 692      * has subsequent characters #x9 (tab), #xA (line feed) and #xD (carriage
 693      * return) , #x20 (space), '1', #x20 (space), <br>
 694      * <b>name</b>: datatype-normalization <br>
 695      * <b>value</b>: true. <br>
 696      * <b>Expected results</b>: after Document.normalizeDocument() is called the
 697      * content of the root is '1'
 698      */
 699     @Test
 700     public void testDatatypeNormalization001() {
 701         Document doc = null;
 702         try {
 703             doc = loadDocument(test1_xsd_url, test_xml);
 704         } catch (Exception e) {
 705             Assert.fail(e.getMessage());
 706         }
 707 
 708         DOMConfiguration config = doc.getDomConfig();
 709 
 710         if (!config.canSetParameter("schema-location", test1_xsd_url) || !config.canSetParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
 711             System.out.println("cannot set the parameters 'schema-location' and 'schema-type'" + " to '" + test1_xsd_url + "' and '"
 712                     + XMLConstants.W3C_XML_SCHEMA_NS_URI + "' respectively");
 713             return;
 714         }
 715         config.setParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI);
 716         config.setParameter("schema-location", test1_xsd_url);
 717 
 718         if (!config.canSetParameter("validate", Boolean.TRUE)) {
 719             System.out.println("OK, setting 'validate' to true is not supported");
 720             return;
 721         }
 722         config.setParameter("validate", Boolean.TRUE);
 723 
 724         if (!config.canSetParameter("datatype-normalization", Boolean.TRUE)) {
 725             System.out.println("OK, setting 'datatype-normalization' to true is not supported");
 726             return;
 727         }
 728         config.setParameter("datatype-normalization", Boolean.TRUE);
 729 
 730         Element root = doc.getDocumentElement();
 731         while (root.getFirstChild() != null) {
 732             root.removeChild(root.getFirstChild());
 733         }
 734         root.appendChild(doc.createTextNode("\t\r\n 1 "));
 735 
 736         setHandler(doc);
 737         doc.normalizeDocument();
 738 
 739         Node child = root.getFirstChild();
 740         if (child == null || child.getNodeType() != Node.TEXT_NODE || !"1".equals(child.getNodeValue())) {
 741             Assert.fail("child: " + child + ", expected: text node '1'");
 742         }
 743 
 744         return; // Status.passed("OK");
 745 
 746     }
 747 
 748     /**
 749      * Equivalence class partitioning with state and input values orientation
 750      * for public void setParameter(String name, Object value) throws
 751      * DOMException, <br>
 752      * <b>pre-conditions</b>: the root element is declared as int and its value
 753      * has subsequent characters #x9 (tab), #xA (line feed) and #xD (carriage
 754      * return) , #x20 (space), '1', #x20 (space), <br>
 755      * <b>name</b>: datatype-normalization <br>
 756      * <b>value</b>: false. <br>
 757      * <b>Expected results</b>: after Document.normalizeDocument() is called the
 758      * value is left unchanged
 759      */
 760     @Test
 761     public void testDatatypeNormalization002() {
 762         Document doc = null;
 763         try {
 764             doc = loadDocument(test1_xsd_url, test_xml);
 765         } catch (Exception e) {
 766             Assert.fail(e.getMessage());
 767         }
 768 
 769         DOMConfiguration config = doc.getDomConfig();
 770 
 771         if (!config.canSetParameter("schema-location", test1_xsd_url) || !config.canSetParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
 772             System.out.println("cannot set the parameters 'schema-location' and 'schema-type'" + " to '" + test1_xsd_url + "' and '"
 773                     + XMLConstants.W3C_XML_SCHEMA_NS_URI + "' respectively");
 774             return;
 775         }
 776         config.setParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI);
 777         config.setParameter("schema-location", test1_xsd_url);
 778 
 779         if (config.canSetParameter("validate", Boolean.TRUE)) {
 780             config.setParameter("validate", Boolean.TRUE);
 781         }
 782 
 783         if (!config.canSetParameter("datatype-normalization", Boolean.FALSE)) {
 784             Assert.fail("datatype-normalization' to false is not supported");
 785         }
 786         config.setParameter("datatype-normalization", Boolean.FALSE);
 787 
 788         Element root = doc.getDocumentElement();
 789         while (root.getFirstChild() != null) {
 790             root.removeChild(root.getFirstChild());
 791         }
 792         String value = "\t\r\n 1 ";
 793         root.appendChild(doc.createTextNode(value));
 794 
 795         setHandler(doc);
 796         doc.normalizeDocument();
 797 
 798         Node child = root.getFirstChild();
 799         if (child == null || child.getNodeType() != Node.TEXT_NODE || !value.equals(child.getNodeValue())) {
 800             Assert.fail("child: " + child + ", expected: '\\t\\r\\n 1 '");
 801         }
 802 
 803         return; // Status.passed("OK");
 804 
 805     }
 806 
 807     /**
 808      * Equivalence class partitioning with state and input values orientation
 809      * for public void setParameter(String name, Object value) throws
 810      * DOMException, <br>
 811      * <b>pre-conditions</b>: the doc contains one entity and one entity
 812      * reference, <br>
 813      * <b>name</b>: entities <br>
 814      * <b>value</b>: true. <br>
 815      * <b>Expected results</b>: the entity and the entity reference are left
 816      * unchanged
 817      */
 818     @Test
 819     public void testEntities001() {
 820         Document doc = null;
 821         try {
 822             doc = loadDocument(null, test1_xml);
 823         } catch (Exception e) {
 824             Assert.fail(e.getMessage());
 825         }
 826 
 827         DOMConfiguration config = doc.getDomConfig();
 828         if (!config.canSetParameter("entities", Boolean.TRUE)) {
 829             Assert.fail("setting 'entities' to true is not supported");
 830         }
 831 
 832         Element root = doc.getDocumentElement();
 833         root.appendChild(doc.createEntityReference("x"));
 834 
 835         config.setParameter("entities", Boolean.TRUE);
 836 
 837         setHandler(doc);
 838         doc.normalizeDocument();
 839         Node child = root.getFirstChild();
 840         if (child == null) {
 841             Assert.fail("root has no child");
 842         }
 843         if (child.getNodeType() != Node.ENTITY_REFERENCE_NODE) {
 844             Assert.fail("root's child is " + child + ", expected entity reference &x;");
 845         }
 846 
 847         if (doc.getDoctype() == null) {
 848             Assert.fail("no doctype found");
 849         }
 850 
 851         if (doc.getDoctype().getEntities() == null) {
 852             Assert.fail("no entitiy found");
 853         }
 854 
 855         if (doc.getDoctype().getEntities().getNamedItem("x") == null) {
 856             Assert.fail("no entitiy with name 'x' found");
 857         }
 858 
 859         return; // Status.passed("OK");
 860     }
 861 
 862     /**
 863      * Equivalence class partitioning with state and input values orientation
 864      * for public void setParameter(String name, Object value) throws
 865      * DOMException, <br>
 866      * <b>pre-conditions</b>: the doc contains one entity and one entity
 867      * reference, <br>
 868      * <b>name</b>: entities <br>
 869      * <b>value</b>: false. <br>
 870      * <b>Expected results</b>: the entity and the entity reference are removed
 871      */
 872     @Test
 873     public void testEntities002() {
 874         Document doc = null;
 875         try {
 876             doc = loadDocument(null, test1_xml);
 877         } catch (Exception e) {
 878             Assert.fail(e.getMessage());
 879         }
 880 
 881         DOMConfiguration config = doc.getDomConfig();
 882         if (!config.canSetParameter("entities", Boolean.FALSE)) {
 883             Assert.fail("setting 'entities' to false is not supported");
 884         }
 885 
 886         Element root = doc.getDocumentElement();
 887         root.appendChild(doc.createEntityReference("x"));
 888 
 889         // TODO: remove debug
 890         NamedNodeMap entities = doc.getDoctype().getEntities();
 891         Entity entityX = (Entity) entities.getNamedItem("x");
 892         System.err.println();
 893         System.err.println("Entity x: " + entityX.getTextContent());
 894         System.err.println();
 895 
 896         config.setParameter("entities", Boolean.FALSE);
 897 
 898         setHandler(doc);
 899         doc.normalizeDocument();
 900         Node child = root.getFirstChild();
 901 
 902         // TODO: restore test, exclude for now to allow other tests to run
 903         /*
 904          * if (child == null) { fail("root has no child"); } if
 905          * (child.getNodeType() != Node.TEXT_NODE ||
 906          * !"X".equals(child.getNodeValue())) { fail("root's child is " + child
 907          * + ", expected text node with value 'X'"); }
 908          *
 909          * if (doc.getDoctype() == null) { fail("no doctype found"); }
 910          *
 911          * if (doc.getDoctype().getEntities() != null &&
 912          * doc.getDoctype().getEntities().getNamedItem("x") != null) {
 913          * fail("entity with name 'x' is found, expected to be removed"); }
 914          */
 915 
 916         return; // Status.passed("OK");
 917     }
 918 
 919     /**
 920      * Equivalence class partitioning with state and input values orientation
 921      * for public void setParameter(String name, Object value) throws
 922      * DOMException, <br>
 923      * <b>pre-conditions</b>: the 'infoset' parameter is set to true, <br>
 924      * <b>name</b>: infoset <br>
 925      * <b>value</b>: false. <br>
 926      * <b>Expected results</b>: the parameters "validate-if-schema", "entities",
 927      * "datatype-normalization", "cdata-sections", "namespace-declarations",
 928      * "well-formed", "element-content-whitespace", "comments", "namespaces" are
 929      * left unchanged
 930      */
 931     @Test
 932     public void testInfoset001() {
 933         Object[][] params = { { "validate-if-schema", Boolean.FALSE }, { "entities", Boolean.FALSE }, { "datatype-normalization", Boolean.FALSE },
 934                 { "cdata-sections", Boolean.FALSE },
 935 
 936                 { "namespace-declarations", Boolean.TRUE }, { "well-formed", Boolean.TRUE }, { "element-content-whitespace", Boolean.TRUE },
 937                 { "comments", Boolean.TRUE }, { "namespaces", Boolean.TRUE }, };
 938 
 939         DOMImplementation domImpl = null;
 940         try {
 941             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
 942         } catch (ParserConfigurationException pce) {
 943             Assert.fail(pce.toString());
 944         } catch (FactoryConfigurationError fce) {
 945             Assert.fail(fce.toString());
 946         }
 947 
 948         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
 949 
 950         DOMConfiguration config = doc.getDomConfig();
 951 
 952         if (!config.canSetParameter("infoset", Boolean.TRUE)) {
 953             Assert.fail("setting 'infoset' to true is not supported");
 954         }
 955 
 956         for (int i = params.length; --i >= 0;) {
 957             Boolean reset = params[i][1].equals(Boolean.TRUE) ? Boolean.FALSE : Boolean.TRUE;
 958             if (config.canSetParameter(params[i][0].toString(), reset)) {
 959                 config.setParameter(params[i][0].toString(), reset);
 960             }
 961         }
 962 
 963         config.setParameter("infoset", Boolean.TRUE);
 964         config.setParameter("infoset", Boolean.FALSE); // has no effect
 965 
 966         StringBuffer result = new StringBuffer();
 967 
 968         for (int i = params.length; --i >= 0;) {
 969             Object param = config.getParameter(params[i][0].toString());
 970             if (!params[i][1].equals(param)) {
 971                 result.append("; the parameter \'" + params[i][0] + "\' is set to " + param + ", expected: " + params[i][1]);
 972             }
 973         }
 974 
 975         if (result.length() > 0) {
 976             Assert.fail(result.toString().substring(2));
 977         }
 978 
 979         return; // Status.passed("OK");
 980     }
 981 
 982     /**
 983      * Equivalence class partitioning with state and input values orientation
 984      * for public void setParameter(String name, Object value) throws
 985      * DOMException, <br>
 986      * <b>pre-conditions</b>: A document with one root element created. The
 987      * prefix 'ns' is bound to 'namespaceURI'. The 'namespaces' parameter is set
 988      * to true, <br>
 989      * <b>name</b>: namespace-declarations <br>
 990      * <b>value</b>: false. <br>
 991      * <b>Expected results</b>: Attribute xmlns:ns="namespaceURI" is not added
 992      * to the root element
 993      */
 994     @Test
 995     public void testNamespaces001() {
 996         DOMImplementation domImpl = null;
 997         try {
 998             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 999             dbf.setNamespaceAware(true);
1000             domImpl = dbf.newDocumentBuilder().getDOMImplementation();
1001         } catch (ParserConfigurationException pce) {
1002             Assert.fail(pce.toString());
1003         } catch (FactoryConfigurationError fce) {
1004             Assert.fail(fce.toString());
1005         }
1006 
1007         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
1008         setHandler(doc);
1009         Element root = doc.getDocumentElement();
1010         DOMConfiguration config = doc.getDomConfig();
1011 
1012         StringBuffer result = new StringBuffer();
1013         if (config.canSetParameter("namespaces", Boolean.FALSE)) {
1014             config.setParameter("namespaces", Boolean.FALSE);
1015 
1016             // namespaces = false
1017             // namespace-declarations = true (default)
1018             doc.normalizeDocument();
1019             String xmlnsNS = root.getAttributeNS(XMLNS, "ns");
1020             if (xmlnsNS.length() > 0) {
1021                 result.append("; the 'namespaces' parameter is set to false but" + "Namespace normalization is performed, attribute" + " xmlns:ns=\"" + xmlnsNS
1022                         + "\" is added");
1023             }
1024         }
1025 
1026         doc = domImpl.createDocument("namespaceURI", "ns:root", null);
1027         root = doc.getDocumentElement();
1028         config = doc.getDomConfig();
1029 
1030         if (!config.canSetParameter("namespaces", Boolean.TRUE)) {
1031             result.append("; setting 'namespaces' to true is not supported");
1032         } else {
1033 
1034             config.setParameter("namespaces", Boolean.TRUE);
1035 
1036             if (!config.canSetParameter("namespace-declarations", Boolean.FALSE)) {
1037                 result.append("; setting 'namespace-declarations' to false is not supported");
1038             } else {
1039                 config.setParameter("namespace-declarations", Boolean.FALSE);
1040 
1041                 // namespaces = true
1042                 // namespace-declarations = false
1043                 doc.normalizeDocument();
1044 
1045                 String xmlnsNS = root.getAttributeNS(XMLNS, "ns");
1046                 if (xmlnsNS.length() > 0) {
1047                     result.append("; namespaces = true, namespace-declarations = false, but" + " xmlns:ns=\"" + xmlnsNS + "\"");
1048                 }
1049             }
1050 
1051             doc = domImpl.createDocument("namespaceURI", "ns:root", null);
1052             setHandler(doc);
1053             root = doc.getDocumentElement();
1054             config = doc.getDomConfig();
1055 
1056             config.setParameter("namespaces", Boolean.TRUE);
1057 
1058             if (!config.canSetParameter("namespace-declarations", Boolean.TRUE)) {
1059                 result.append("; setting 'namespace-declarations' to true is not supported");
1060             } else {
1061                 config.setParameter("namespace-declarations", Boolean.TRUE);
1062 
1063                 // namespaces = true
1064                 // namespace-declarations = true
1065                 doc.normalizeDocument();
1066 
1067                 String xmlnsNS = root.getAttributeNS(XMLNS, "ns");
1068                 if (!"namespaceURI".equals(xmlnsNS)) {
1069                     result.append("; namespaces = true, namespace-declarations = true, but" + " xmlns:ns=\"" + xmlnsNS + "\"");
1070                 }
1071             }
1072         }
1073 
1074         if (result.length() > 0) {
1075             Assert.fail(result.toString().substring(2));
1076         }
1077         return; // Status.passed("OK");
1078     }
1079 
1080     /**
1081      * Equivalence class partitioning with state and input values orientation
1082      * for public void setParameter(String name, Object value) throws
1083      * DOMException, <br>
1084      * <b>pre-conditions</b>: an attribute value is not fully normalized, <br>
1085      * <b>name</b>: normalize-characters <br>
1086      * <b>value</b>: false. <br>
1087      * <b>Expected results</b>: Node.normalize() leaves the value unchanged
1088      */
1089     @Test
1090     public void testNormalizeCharacters001() {
1091         DOMImplementation domImpl = null;
1092         try {
1093             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
1094         } catch (ParserConfigurationException pce) {
1095             Assert.fail(pce.toString());
1096         } catch (FactoryConfigurationError fce) {
1097             Assert.fail(fce.toString());
1098         }
1099 
1100         Document doc = domImpl.createDocument(null, null, null);
1101 
1102         Attr attr = doc.createAttribute("attr");
1103         String notNormalized = " \u0073\u0075\u0063\u0327\u006F\u006E ";
1104         attr.setValue(notNormalized);
1105 
1106         DOMConfiguration config = doc.getDomConfig();
1107 
1108         StringBuffer result = new StringBuffer();
1109         if (!config.canSetParameter("normalize-characters", Boolean.FALSE)) {
1110             result.append("; setting 'normalize-characters' to false is not supported");
1111         } else {
1112 
1113             config.setParameter("normalize-characters", Boolean.FALSE);
1114 
1115             attr.normalize();
1116 
1117             String value = attr.getValue();
1118             if (!notNormalized.equals(value)) {
1119                 result.append("; the value is normalized to '" + value + "', expected to stay unchanged");
1120             }
1121         }
1122 
1123         if (config.canSetParameter("normalize-characters", Boolean.TRUE)) {
1124             config.setParameter("normalize-characters", Boolean.TRUE);
1125 
1126             attr.setValue(notNormalized);
1127             attr.normalize();
1128 
1129             String value = attr.getValue();
1130             if (notNormalized.equals(value)) {
1131                 result.append("; the value is not normalized: '" + value + "', expected: '\u0073\u0075\u00E7\u006F\u006E'");
1132             }
1133         }
1134 
1135         if (result.length() > 0) {
1136             Assert.fail(result.toString().substring(2));
1137         }
1138         return; // Status.passed("OK");
1139 
1140     }
1141 
1142     /**
1143      * Equivalence class partitioning with state and input values orientation
1144      * for public void setParameter(String name, Object value) throws
1145      * DOMException, <br>
1146      * <b>pre-conditions</b>: The root element has invalid content. The
1147      * 'validate' parameter is set to true. The 'schema-location' parameter is
1148      * set to 'DOMConfigurationTest.xsd'., <br>
1149      * <b>name</b>: schema-type <br>
1150      * <b>value</b>: http://www.w3.org/2001/XMLSchema. <br>
1151      * <b>Expected results</b>: An error is reported
1152      */
1153     @Test
1154     public void testValidate001() {
1155         DOMImplementation domImpl = null;
1156         try {
1157             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1158             dbf.setNamespaceAware(true);
1159             dbf.setValidating(true);
1160             domImpl = dbf.newDocumentBuilder().getDOMImplementation();
1161         } catch (ParserConfigurationException pce) {
1162             Assert.fail(pce.toString());
1163         } catch (FactoryConfigurationError fce) {
1164             Assert.fail(fce.toString());
1165         }
1166 
1167         Document doc = domImpl.createDocument("test", "ns:root", null);
1168 
1169         Element root = doc.getDocumentElement();
1170         root.appendChild(doc.createTextNode("xxx")); // invalid value
1171 
1172         DOMConfiguration config = doc.getDomConfig();
1173 
1174         if (!config.canSetParameter("schema-location", test1_xsd_url) || !config.canSetParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
1175             System.out.println("cannot set the parameters 'schema-location' and 'schema-type'" + " to '" + test1_xsd_url + "' and '"
1176                     + XMLConstants.W3C_XML_SCHEMA_NS_URI + "' respectively");
1177             return;
1178         }
1179         config.setParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI);
1180         config.setParameter("schema-location", test1_xsd_url);
1181 
1182         String resultOK = "OK";
1183         StringBuffer result = new StringBuffer();
1184         if (!config.canSetParameter("validate", Boolean.TRUE)) {
1185             resultOK = "OK, setting the parameter 'validate' to true is not supported";
1186         } else {
1187             config.setParameter("validate", Boolean.TRUE);
1188             TestHandler testHandler = new TestHandler();
1189             config.setParameter("error-handler", testHandler);
1190             doc.normalizeDocument();
1191             if (testHandler.getError() == null && null == testHandler.getFatalError()) {
1192                 result.append("; no error was reported when the 'validate' is set to true");
1193             }
1194         }
1195 
1196         if (!config.canSetParameter("validate", Boolean.FALSE)) {
1197             result.append("; cannot set the parameters 'validate' to false");
1198         } else {
1199             config.setParameter("validate", Boolean.FALSE);
1200             TestHandler testHandler = new TestHandler();
1201             config.setParameter("error-handler", testHandler);
1202             doc.normalizeDocument();
1203             if (testHandler.getError() != null || null != testHandler.getFatalError()) {
1204                 result.append("; unexpected error: " + testHandler.getFatalError() + "; " + testHandler.getError());
1205             }
1206         }
1207 
1208         if (result.length() > 0) {
1209             Assert.fail(result.toString().substring(2));
1210         }
1211         return; // Status.passed(resultOK);
1212 
1213     }
1214 
1215     /**
1216      * Equivalence class partitioning with state and input values orientation
1217      * for public void setParameter(String name, Object value) throws
1218      * DOMException, <br>
1219      * <b>pre-conditions</b>: The root contains a CDATASection with the
1220      * termination marker ']]&gt;', <br>
1221      * <b>name</b>: split-cdata-sections <br>
1222      * <b>value</b>: true. <br>
1223      * <b>Expected results</b>: A warning is reported when the section is
1224      * splitted
1225      */
1226     @Test
1227     public void testSplitCDATA001() {
1228         DOMImplementation domImpl = null;
1229         try {
1230             domImpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation();
1231         } catch (ParserConfigurationException pce) {
1232             Assert.fail(pce.toString());
1233         } catch (FactoryConfigurationError fce) {
1234             Assert.fail(fce.toString());
1235         }
1236 
1237         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
1238 
1239         DOMConfiguration config = doc.getDomConfig();
1240         CDATASection cdata = doc.createCDATASection("text]" + "]>text");
1241         doc.getDocumentElement().appendChild(cdata);
1242 
1243         TestHandler testHandler = new TestHandler();
1244         config.setParameter("error-handler", testHandler);
1245 
1246         if (!config.canSetParameter("split-cdata-sections", Boolean.TRUE)) {
1247             Assert.fail("cannot set the parameters 'split-cdata-sections' to true");
1248         }
1249         config.setParameter("split-cdata-sections", Boolean.TRUE);
1250 
1251         doc.normalizeDocument();
1252         if (null == testHandler.getWarning()) {
1253             Assert.fail("no warning is reported");
1254         }
1255 
1256         return; // Status.passed("OK");
1257 
1258     }
1259 
1260     /**
1261      * Equivalence class partitioning with state and input values orientation
1262      * for public void setParameter(String name, Object value) throws
1263      * DOMException, <br>
1264      * <b>pre-conditions</b>: The root contains a CDATASection with the
1265      * termination marker ']]&gt;', <br>
1266      * <b>name</b>: split-cdata-sections <br>
1267      * <b>value</b>: false. <br>
1268      * <b>Expected results</b>: No warning is reported
1269      */
1270     @Test
1271     public void testSplitCDATA002() {
1272         DOMImplementation domImpl = null;
1273         try {
1274             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1275             dbf.setNamespaceAware(true);
1276             dbf.setValidating(true);
1277             domImpl = dbf.newDocumentBuilder().getDOMImplementation();
1278         } catch (ParserConfigurationException pce) {
1279             Assert.fail(pce.toString());
1280         } catch (FactoryConfigurationError fce) {
1281             Assert.fail(fce.toString());
1282         }
1283 
1284         Document doc = domImpl.createDocument("namespaceURI", "ns:root", null);
1285 
1286         DOMConfiguration config = doc.getDomConfig();
1287         CDATASection cdata = doc.createCDATASection("text]" + "]>text");
1288         doc.getDocumentElement().appendChild(cdata);
1289 
1290         TestHandler testHandler = new TestHandler();
1291         config.setParameter("error-handler", testHandler);
1292 
1293         if (!config.canSetParameter("split-cdata-sections", Boolean.FALSE)) {
1294             Assert.fail("cannot set the parameters 'split-cdata-sections' to false");
1295         }
1296         config.setParameter("split-cdata-sections", Boolean.FALSE);
1297 
1298         doc.normalizeDocument();
1299         if (null == testHandler.getError()) {
1300             Assert.fail("no error is reported");
1301         }
1302 
1303         return; // Status.passed("OK");
1304 
1305     }
1306 
1307     /**
1308      * Equivalence class partitioning with state and input values orientation
1309      * for public void setParameter(String name, Object value) throws
1310      * DOMException, <br>
1311      * <b>pre-conditions</b>: The root element has invalid content. The schema
1312      * is specified by setting the 'schema-location' and the 'schema-type'
1313      * parameters., <br>
1314      * <b>name</b>: validate-if-schema <br>
1315      * <b>value</b>: false. <br>
1316      * <b>Expected results</b>: No error is reported
1317      */
1318     @Test
1319     public void testValidateIfSchema001() {
1320         DOMImplementation domImpl = null;
1321         try {
1322             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1323             dbf.setNamespaceAware(true);
1324             dbf.setValidating(true);
1325             domImpl = dbf.newDocumentBuilder().getDOMImplementation();
1326         } catch (ParserConfigurationException pce) {
1327             Assert.fail(pce.toString());
1328         } catch (FactoryConfigurationError fce) {
1329             Assert.fail(fce.toString());
1330         }
1331 
1332         Document doc = domImpl.createDocument("test", "ns:root", null);
1333 
1334         Element root = doc.getDocumentElement();
1335         root.appendChild(doc.createTextNode("xxx")); // invalid value
1336 
1337         DOMConfiguration config = doc.getDomConfig();
1338 
1339         if (!config.canSetParameter("schema-location", test1_xsd_url) || !config.canSetParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
1340             System.out.println("cannot set the parameters 'schema-location' and 'schema-type'" + " to 'DOMConfigurationTest.xsd' and '"
1341                     + XMLConstants.W3C_XML_SCHEMA_NS_URI + "' respectively");
1342             return;
1343         }
1344         config.setParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI);
1345         config.setParameter("schema-location", test1_xsd_url);
1346 
1347         String resultOK = "OK";
1348         StringBuffer result = new StringBuffer();
1349         if (!config.canSetParameter("validate-if-schema", Boolean.FALSE)) {
1350             result.append("; cannot set the parameters 'validate-if-schema' to false");
1351         } else {
1352             config.setParameter("validate-if-schema", Boolean.FALSE);
1353             TestHandler testHandler = new TestHandler();
1354             config.setParameter("error-handler", testHandler);
1355             doc.normalizeDocument();
1356             if (testHandler.getError() != null || null != testHandler.getFatalError()) {
1357                 result.append("; unexpected error: " + testHandler.getFatalError() + "; " + testHandler.getError());
1358             }
1359         }
1360 
1361         if (!config.canSetParameter("validate-if-schema", Boolean.TRUE)) {
1362             resultOK = "OK, setting the parameter 'validate-if-schema' to true is not supported";
1363         } else {
1364             config.setParameter("validate-if-schema", Boolean.TRUE);
1365             TestHandler testHandler = new TestHandler();
1366             config.setParameter("error-handler", testHandler);
1367             doc.normalizeDocument();
1368             if (testHandler.getError() == null && null == testHandler.getFatalError()) {
1369                 result.append("; no error was reported when the 'validate-if-schema' is set to true");
1370             }
1371         }
1372 
1373         if (result.length() > 0) {
1374             Assert.fail(result.toString().substring(2));
1375         }
1376         return; // Status.passed(resultOK);
1377 
1378     }
1379 
1380     /**
1381      * Equivalence class partitioning with state and input values orientation
1382      * for public void setParameter(String name, Object value) throws
1383      * DOMException, <br>
1384      * <b>pre-conditions</b>: The root element is not declared in the schema
1385      * specified by setting the 'schema-location' and the 'schema-type'
1386      * parameters., <br>
1387      * <b>name</b>: validate-if-schema <br>
1388      * <b>value</b>: true. <br>
1389      * <b>Expected results</b>: No error is reported
1390      */
1391     @Test
1392     public void testValidateIfSchema002() {
1393         DOMImplementation domImpl = null;
1394         try {
1395             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1396             dbf.setNamespaceAware(true);
1397             dbf.setValidating(true);
1398             domImpl = dbf.newDocumentBuilder().getDOMImplementation();
1399         } catch (ParserConfigurationException pce) {
1400             Assert.fail(pce.toString());
1401         } catch (FactoryConfigurationError fce) {
1402             Assert.fail(fce.toString());
1403         }
1404 
1405         Document doc = domImpl.createDocument("test", "ns:undeclared_root", null);
1406 
1407         Element root = doc.getDocumentElement();
1408         root.appendChild(doc.createTextNode("xxx"));
1409 
1410         DOMConfiguration config = doc.getDomConfig();
1411 
1412         if (!config.canSetParameter("schema-location", test1_xsd_url) || !config.canSetParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
1413             System.out.println("cannot set the parameters 'schema-location' and 'schema-type'" + " to 'DOMConfigurationTest.xsd' and '"
1414                     + XMLConstants.W3C_XML_SCHEMA_NS_URI + "' respectively");
1415             return;
1416         }
1417         config.setParameter("schema-type", XMLConstants.W3C_XML_SCHEMA_NS_URI);
1418         config.setParameter("schema-location", test1_xsd_url);
1419 
1420         if (!config.canSetParameter("validate-if-schema", Boolean.TRUE)) {
1421             System.out.println("OK, setting the parameter 'validate-if-schema'" + " to true is not supported");
1422             return;
1423         }
1424 
1425         config.setParameter("validate-if-schema", Boolean.TRUE);
1426         TestHandler testHandler = new TestHandler();
1427         config.setParameter("error-handler", testHandler);
1428         doc.normalizeDocument();
1429         if (testHandler.getError() != null || null != testHandler.getFatalError()) {
1430             Assert.fail("unexpected error: " + testHandler.getFatalError() + "; " + testHandler.getError());
1431         }
1432         return; // Status.passed("OK");
1433 
1434     }
1435 
1436     /**
1437      * Equivalence class partitioning with state and input values orientation
1438      * for public void setParameter(String name, Object value) throws
1439      * DOMException, <br>
1440      * <b>pre-conditions</b>: the attribute has EntityReference to '&lt;', <br>
1441      * <b>name</b>: well-formed <br>
1442      * <b>value</b>: true. <br>
1443      * <b>Expected results</b>: An error is reported
1444      */
1445     @Test
1446     public void testWellFormed001() {
1447         Document doc = null;
1448         try {
1449             doc = loadDocument(null, test2_xml);
1450         } catch (Exception e) {
1451             Assert.fail(e.getMessage());
1452         }
1453 
1454         DOMConfiguration config = doc.getDomConfig();
1455         if (!config.canSetParameter("well-formed", Boolean.TRUE)) {
1456             Assert.fail("setting 'well-formed' to true is not supported");
1457         }
1458         config.setParameter("well-formed", Boolean.TRUE);
1459 
1460         Element root = doc.getDocumentElement();
1461 
1462         Attr attr = doc.createAttributeNS(null, "attr");
1463 
1464         try {
1465             attr.appendChild(doc.createEntityReference("<"));
1466         } catch (DOMException domException) {
1467             System.out.println("testWellFormed001: Expected DOMException for Attribute value = '<'" + domException.toString());
1468             return; // OK
1469         }
1470 
1471         root.setAttributeNode(attr);
1472 
1473         TestHandler testHandler = new TestHandler();
1474         config.setParameter("error-handler", testHandler);
1475 
1476         doc.normalizeDocument();
1477 
1478         if (testHandler.getError() == null && null == testHandler.getFatalError()) {
1479             Assert.fail("no error was reported when attribute has <");
1480         }
1481 
1482         return; // Status.passed("OK");
1483     }
1484 
1485     /**
1486      * Equivalence class partitioning with state and input values orientation
1487      * for public void setParameter(String name, Object value) throws
1488      * DOMException, <br>
1489      * <b>pre-conditions</b>: the attribute has EntityReference to '&lt;', <br>
1490      * <b>name</b>: well-formed <br>
1491      * <b>value</b>: false. <br>
1492      * <b>Expected results</b>: No error is reported
1493      */
1494     @Test
1495     public void testWellFormed002() {
1496         Document doc = null;
1497         try {
1498             doc = loadDocument(null, test2_xml);
1499         } catch (Exception e) {
1500             Assert.fail(e.getMessage());
1501         }
1502 
1503         DOMConfiguration config = doc.getDomConfig();
1504         if (!config.canSetParameter("well-formed", Boolean.FALSE)) {
1505             System.out.println("OK, setting 'well-formed' to false is not supported");
1506             return;
1507         }
1508         config.setParameter("well-formed", Boolean.FALSE);
1509 
1510         Element root = doc.getDocumentElement();
1511 
1512         Attr attr = doc.createAttributeNS(null, "attr");
1513         attr.appendChild(doc.createEntityReference("x"));
1514 
1515         root.setAttributeNode(attr);
1516 
1517         TestHandler testHandler = new TestHandler();
1518         config.setParameter("error-handler", testHandler);
1519 
1520         doc.normalizeDocument();
1521 
1522         if (testHandler.getError() != null || null != testHandler.getFatalError()) {
1523             Assert.fail("unexpected error: " + testHandler.getFatalError() + "; " + testHandler.getError());
1524         }
1525 
1526         return; // Status.passed("OK");
1527 
1528     }
1529 
1530     /**
1531      * Equivalence class partitioning with state and input values orientation
1532      * for public void setParameter(String name, Object value) throws
1533      * DOMException, <br>
1534      * <b>pre-conditions</b>: the document root element has a text node with
1535      * four white space characters, <br>
1536      * <b>name</b>: element-content-whitespace <br>
1537      * <b>value</b>: true. <br>
1538      * <b>Expected results</b>: the text node is preserved
1539      */
1540     @Test
1541     public void testECWhitespace001() {
1542         Document doc = null;
1543         try {
1544             doc = loadDocument(null, test3_xml);
1545         } catch (Exception e) {
1546             Assert.fail(e.getMessage());
1547         }
1548 
1549         Element root = doc.getDocumentElement();
1550         Text text = doc.createTextNode("\t\n\r ");
1551         root.appendChild(text);
1552 
1553         DOMConfiguration config = doc.getDomConfig();
1554         if (!config.canSetParameter("element-content-whitespace", Boolean.TRUE)) {
1555             Assert.fail("setting 'element-content-whitespace' to true is not supported");
1556         }
1557         config.setParameter("element-content-whitespace", Boolean.TRUE);
1558 
1559         if (!config.canSetParameter("validate", Boolean.TRUE)) {
1560             System.out.println("OK, setting 'validate' to true is not supported");
1561             return;
1562         }
1563         config.setParameter("validate", Boolean.TRUE);
1564 
1565         setHandler(doc);
1566         doc.normalizeDocument();
1567 
1568         Node firstChild = root.getFirstChild();
1569         if (firstChild == null || firstChild.getNodeType() != Node.TEXT_NODE || !((Text) firstChild).isElementContentWhitespace()) {
1570             Assert.fail("the first child is " + firstChild + ", expected a text node with the four whitespace characters");
1571         }
1572 
1573         return; // Status.passed("OK");
1574 
1575     }
1576 
1577     /**
1578      * Equivalence class partitioning with state and input values orientation
1579      * for public void setParameter(String name, Object value) throws
1580      * DOMException, <br>
1581      * <b>pre-conditions</b>: the document root element has a text node with
1582      * four white space characters, <br>
1583      * <b>name</b>: element-content-whitespace <br>
1584      * <b>value</b>: false. <br>
1585      * <b>Expected results</b>: the text node is discarded
1586      */
1587     @Test
1588     public void testECWhitespace002() {
1589         Document doc = null;
1590         try {
1591             doc = loadDocument(null, test3_xml);
1592         } catch (Exception e) {
1593             Assert.fail(e.getMessage());
1594         }
1595 
1596         Element root = doc.getDocumentElement();
1597         Text text = doc.createTextNode("\t\n\r ");
1598         root.appendChild(text);
1599 
1600         DOMConfiguration config = doc.getDomConfig();
1601         if (!config.canSetParameter("element-content-whitespace", Boolean.FALSE)) {
1602             System.out.println("OK, setting 'element-content-whitespace' to false is not supported");
1603             return;
1604         }
1605         config.setParameter("element-content-whitespace", Boolean.FALSE);
1606 
1607         if (!config.canSetParameter("validate", Boolean.TRUE)) {
1608             System.out.println("OK, setting 'validate' to true is not supported");
1609             return;
1610         }
1611         config.setParameter("validate", Boolean.TRUE);
1612 
1613         setHandler(doc);
1614         doc.normalizeDocument();
1615 
1616         Node firstChild = root.getFirstChild();
1617         if (firstChild != null) {
1618             Assert.fail("the first child is " + firstChild + ", but no child is expected");
1619         }
1620 
1621         return; // Status.passed("OK");
1622 
1623     }
1624 }