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.StringBufferInputStream; 28 29 import javax.xml.parsers.DocumentBuilder; 30 import javax.xml.parsers.DocumentBuilderFactory; 31 import javax.xml.parsers.ParserConfigurationException; 32 33 import org.testng.Assert; 34 import org.testng.annotations.Listeners; 35 import org.testng.annotations.Test; 36 import org.w3c.dom.Attr; 37 import org.w3c.dom.DOMImplementation; 38 import org.w3c.dom.Document; 39 import org.w3c.dom.Element; 40 import org.w3c.dom.NamedNodeMap; 41 import org.w3c.dom.Node; 42 import org.w3c.dom.NodeList; 43 import org.w3c.dom.ls.DOMImplementationLS; 44 import org.w3c.dom.ls.LSInput; 45 import org.w3c.dom.ls.LSParser; 46 import org.w3c.dom.ls.LSParserFilter; 47 import org.w3c.dom.traversal.NodeFilter; 48 import org.xml.sax.SAXException; 49 50 /* 51 * @test 52 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest 53 * @run testng/othervm -DrunSecMngr=true dom.ls.LSParserTCKTest 54 * @run testng/othervm dom.ls.LSParserTCKTest 55 * @summary Test Specifications and Descriptions for LSParser. 56 */ 57 @Listeners({jaxp.library.BasePolicy.class}) 58 public class LSParserTCKTest { 59 60 DOMImplementationLS implLS = null; 61 public String xml1 = "<?xml version=\"1.0\"?><ROOT><ELEMENT1><CHILD1/><CHILD1><COC1/></CHILD1></ELEMENT1><ELEMENT2>test1<CHILD2/></ELEMENT2></ROOT>"; 62 63 /** 64 * Equivalence class partitioning 65 * with state, input and output values orientation 66 * for public Document parse(LSInput is), 67 * <br><b>pre-conditions</b>: set filter that REJECTs any CHILD* node, 68 * <br><b>is</b>: xml1 69 * <br><b>output</b>: XML document with ELEMNENT1 and ELEMENT2 only. 70 */ 71 @Test 72 public void testfilter0001() { 73 LSParser parser = createLSParser(); 74 if (parser == null) { 75 Assert.fail("Unable to create LSParser!"); 76 } 77 // set filter 78 parser.setFilter(new LSParserFilter() { 79 public short startElement(Element elt) { 80 return FILTER_ACCEPT; 81 } 82 83 public short acceptNode(Node enode) { 84 if (enode.getNodeName().startsWith("CHILD")) { 85 return FILTER_REJECT; 86 } 87 return FILTER_ACCEPT; 88 } 89 90 public int getWhatToShow() { 91 return NodeFilter.SHOW_ALL; 92 } 93 }); 94 String expected = "<?xml version=\"1.0\"?><ROOT><ELEMENT1></ELEMENT1><ELEMENT2>test1</ELEMENT2></ROOT>"; 95 Document doc = parser.parse(getXmlSource(xml1)); 96 if (!match(expected, doc)) { 97 Assert.fail("DOM structure after parsing is not equal to a structure of XML document, that being parsed"); 98 } 99 100 System.out.println("OKAY"); 101 } 102 103 public LSParserTCKTest(String name) { 104 init(); 105 } 106 107 protected void init() { 108 Document doc = null; 109 DocumentBuilder parser = null; 110 try { 111 parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 112 } catch (ParserConfigurationException e) { 113 e.printStackTrace(); 114 } 115 StringBufferInputStream is = new StringBufferInputStream(xml1); 116 try { 117 doc = parser.parse(is); 118 } catch (SAXException e) { 119 e.printStackTrace(); 120 } catch (IOException e) { 121 e.printStackTrace(); 122 } 123 DOMImplementation impl = doc.getImplementation(); 124 implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0"); 125 } 126 127 public LSInput getXmlSource(String xmldoc) { 128 LSInput srcdoc = createLSInput(); 129 srcdoc.setStringData(xmldoc); 130 return srcdoc; 131 } 132 133 public LSInput createLSInput() { 134 return implLS.createLSInput(); 135 } 136 137 public LSParser createLSParser() { 138 return implLS.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, "http://www.w3.org/2001/XMLSchema"); 139 } 140 141 public boolean match(String template, Node source) { 142 LSParser dp = createLSParser(); 143 if (dp == null) { 144 System.out.println("Can not create LSParser."); 145 return false; 146 } 147 LSInput src = getXmlSource(template); 148 Document doc = dp.parse(src); 149 return checkXMLs(doc, source); 150 } 151 152 // ========================== XML comparison code ============== 153 public boolean checkXMLs(Node template, Node source) { 154 if (source == null || template == null) { 155 return template == source; 156 } 157 String tname = template.getLocalName(); 158 String tvalue = template.getNodeValue(); 159 NamedNodeMap tattr = template.getAttributes(); 160 NodeList tchildren = template.getChildNodes(); 161 162 String sname = source.getLocalName(); 163 String svalue = source.getNodeValue(); 164 NamedNodeMap sattr = source.getAttributes(); 165 NodeList schildren = source.getChildNodes(); 166 if (tname != null && !tname.equals(sname)) { 167 return false; 168 } 169 if (tvalue != null && !tvalue.equals(svalue)) { 170 return false; 171 } 172 if (tattr != null && sattr != null) { 173 if (sattr.getLength() != tattr.getLength()) { 174 return false; 175 } 176 for (int i = 0; i < tattr.getLength(); i++) { 177 Attr t = (Attr) tattr.item(i); 178 Attr s = (Attr) sattr.getNamedItem(t.getName()); 179 if (!checkXMLAttrs(t, s)) { 180 // ref.println(sname+": [expected attr: " + t + 181 // "; actual attr: " +s+"]"); 182 return false; 183 } 184 } 185 } else if (tattr != null || sattr != null) { 186 return false; 187 } 188 189 for (int i = 0; i < tchildren.getLength(); i++) { 190 if (!checkXMLs(tchildren.item(i), schildren.item(i))) { 191 // ref.println(sname+": [expected node: "+tchildren.item(i) 192 // +"; actual node: "+schildren.item(i)+"]"); 193 return false; 194 } 195 } 196 return true; 197 } 198 199 public boolean checkXMLAttrs(Attr template, Attr source) { 200 if (source == null || template == null) { 201 return template == source; 202 } 203 String tname = template.getName(); 204 String tvalue = template.getValue(); 205 String sname = source.getName(); 206 String svalue = source.getValue(); 207 System.out.println("Attr:" + tname + "?" + sname); 208 if (tname != null && !tname.equals(sname)) { 209 // ref.println("Attr Name:" + tname + "!=" + sname); 210 return false; 211 } 212 if (tvalue != null && !tvalue.equals(svalue)) { 213 // ref.println("Attr value:" + tvalue + "!=" + svalue); 214 return false; 215 } 216 // ref.println("Attr:" + tname + ":" + tvalue + "=" + sname + ":" + 217 // svalue); 218 return true; 219 } 220 221 /** 222 * Equivalence class partitioning with state, input and output values 223 * orientation for public Document parse(LSInput is), <br> 224 * <b>pre-conditions</b>: set filter that SKIPs ELEMENT1 node, <br> 225 * <b>is</b>: xml1 <br> 226 * <b>output</b>: XML document with CHILD1 and ELEMENT2 only. 227 */ 228 @Test 229 public void testFilter0002() { 230 LSParser parser = createLSParser(); 231 if (parser == null) { 232 Assert.fail("Unable to create LSParser!"); 233 } 234 // set filter 235 parser.setFilter(new LSParserFilter() { 236 public short startElement(Element elt) { 237 return FILTER_ACCEPT; 238 } 239 240 public short acceptNode(Node enode) { 241 if (enode.getNodeName().startsWith("ELEMENT1")) { 242 return FILTER_SKIP; 243 } 244 return FILTER_ACCEPT; 245 } 246 247 public int getWhatToShow() { 248 return NodeFilter.SHOW_ALL; 249 } 250 }); 251 String expected = "<?xml version=\"1.0\"?><ROOT><CHILD1/><CHILD1><COC1/></CHILD1><ELEMENT2>test1<CHILD2/></ELEMENT2></ROOT>"; 252 Document doc = parser.parse(getXmlSource(xml1)); 253 if (!match(expected, doc)) { 254 Assert.fail("DOM structure after parsing is not equal to a structure of XML document, that being parsed"); 255 } 256 System.out.println("OKAY"); 257 } 258 259 /** 260 * Equivalence class partitioning with state, input and output values 261 * orientation for public Document parse(LSInput is), <br> 262 * <b>pre-conditions</b>: set filter that SKIPs ELEMENT1 node, <br> 263 * <b>is</b>: xml1 <br> 264 * <b>output</b>: XML document with ELEMENT1 only. 265 */ 266 @Test 267 public void testFilter0003() { 268 LSParser parser = createLSParser(); 269 if (parser == null) { 270 Assert.fail("Unable to create LSParser!"); 271 } 272 // set filter 273 parser.setFilter(new LSParserFilter() { 274 public short startElement(Element elt) { 275 return FILTER_ACCEPT; 276 } 277 278 public short acceptNode(Node enode) { 279 if (enode.getNodeName().startsWith("ELEMENT2")) { 280 return FILTER_INTERRUPT; 281 } 282 return FILTER_ACCEPT; 283 } 284 285 public int getWhatToShow() { 286 return NodeFilter.SHOW_ALL; 287 } 288 }); 289 String expected = "<ROOT><ELEMENT1><CHILD1/><CHILD1><COC1/></CHILD1></ELEMENT1></ROOT>"; 290 Document doc = parser.parse(getXmlSource(xml1)); 291 if (!match(expected, doc)) { 292 Assert.fail("DOM structure after parsing is not equal to a structure of XML document, that being parsed"); 293 } 294 System.out.println("OKAY"); 295 } 296 297 /** 298 * Equivalence class partitioning with state, input and output values 299 * orientation for public Document parse(LSInput is), <br> 300 * <b>pre-conditions</b>: set filter that accepts all, <br> 301 * <b>is</b>: xml1 <br> 302 * <b>output</b>: full XML document. 303 */ 304 @Test 305 public void testFilter0004() { 306 LSParser parser = createLSParser(); 307 if (parser == null) { 308 Assert.fail("Unable to create LSParser!"); 309 } 310 // set filter 311 parser.setFilter(new LSParserFilter() { 312 public short startElement(Element elt) { 313 return FILTER_ACCEPT; 314 } 315 316 public short acceptNode(Node enode) { 317 return FILTER_ACCEPT; 318 } 319 320 public int getWhatToShow() { 321 return NodeFilter.SHOW_ALL; 322 } 323 }); 324 String expected = "<ROOT><ELEMENT1><CHILD1/><CHILD1><COC1/></CHILD1></ELEMENT1><ELEMENT2>test1<CHILD2/></ELEMENT2></ROOT>"; 325 Document doc = parser.parse(getXmlSource(xml1)); 326 if (!match(expected, doc)) { 327 Assert.fail("DOM structure after parsing is not equal to a structure of XML document, that being parsed"); 328 } 329 System.out.println("OKAY"); 330 } 331 332 /** 333 * Equivalence class partitioning with state, input and output values 334 * orientation for public Document parse(LSInput is), <br> 335 * <b>pre-conditions</b>: set filter that REJECTs all, <br> 336 * <b>is</b>: xml1 <br> 337 * <b>output</b>: empty XML document. 338 */ 339 @Test 340 public void testFilter0005() { 341 LSParser parser = createLSParser(); 342 if (parser == null) { 343 Assert.fail("Unable to create LSParser!"); 344 } 345 // set filter 346 parser.setFilter(new LSParserFilter() { 347 public short startElement(Element elt) { 348 return FILTER_ACCEPT; 349 } 350 351 public short acceptNode(Node enode) { 352 return FILTER_REJECT; 353 } 354 355 public int getWhatToShow() { 356 return NodeFilter.SHOW_ALL; 357 } 358 }); 359 Document doc = parser.parse(getXmlSource(xml1)); 360 NodeList children = doc.getDocumentElement().getChildNodes(); 361 if (children.getLength() != 0) { 362 Assert.fail("Not all children skipped"); 363 } 364 System.out.println("OKAY"); 365 } 366 367 /** 368 * Equivalence class partitioning with state, input and output values 369 * orientation for public Document parse(LSInput is), <br> 370 * <b>pre-conditions</b>: set filter that SKIPs all, <br> 371 * <b>is</b>: xml1 <br> 372 * <b>output</b>: empty XML document. 373 */ 374 @Test 375 public void testFilter0006() { 376 LSParser parser = createLSParser(); 377 if (parser == null) { 378 Assert.fail("Unable to create LSParser!"); 379 } 380 // set filter 381 parser.setFilter(new LSParserFilter() { 382 public short startElement(Element elt) { 383 return FILTER_ACCEPT; 384 } 385 386 public short acceptNode(Node enode) { 387 return FILTER_SKIP; 388 } 389 390 public int getWhatToShow() { 391 return NodeFilter.SHOW_ALL; 392 } 393 }); 394 Document doc = parser.parse(getXmlSource(xml1)); 395 NodeList children = doc.getDocumentElement().getChildNodes(); 396 if (children.getLength() != 0) { 397 Assert.fail("Not all children skipped"); 398 } 399 System.out.println("OKAY"); 400 } 401 402 /** 403 * Equivalence class partitioning with state, input and output values 404 * orientation for public Document parse(LSInput is), <br> 405 * <b>pre-conditions</b>: set filter that REJECTs any CHILD* start element, <br> 406 * <b>is</b>: xml1 <br> 407 * <b>output</b>: XML document with ELEMENT1 and ELEMENT2 only. 408 */ 409 @Test 410 public void testFilter0007() { 411 LSParser parser = createLSParser(); 412 if (parser == null) { 413 Assert.fail("Unable to create LSParser!"); 414 } 415 // set filter 416 parser.setFilter(new LSParserFilter() { 417 public short startElement(Element elt) { 418 if (elt.getTagName().startsWith("CHILD")) { 419 return FILTER_REJECT; 420 } 421 return FILTER_ACCEPT; 422 } 423 424 public short acceptNode(Node enode) { 425 return FILTER_ACCEPT; 426 } 427 428 public int getWhatToShow() { 429 return NodeFilter.SHOW_ALL; 430 } 431 }); 432 String expected = "<?xml version=\"1.0\"?><ROOT><ELEMENT1></ELEMENT1><ELEMENT2>test1</ELEMENT2></ROOT>"; 433 Document doc = parser.parse(getXmlSource(xml1)); 434 if (!match(expected, doc)) { 435 Assert.fail("DOM structure after parsing is not equal to a structure of XML document, that being parsed"); 436 } 437 System.out.println("OKAY"); 438 } 439 440 /** 441 * Equivalence class partitioning with state, input and output values 442 * orientation for public Document parse(LSInput is), <br> 443 * <b>pre-conditions</b>: set filter that SKIPs ELEMENT1 start element, <br> 444 * <b>is</b>: xml1 <br> 445 * <b>output</b>: XML document with CHILD1 and ELEMENT2 only. 446 */ 447 @Test 448 public void testFilter0008() { 449 LSParser parser = createLSParser(); 450 if (parser == null) { 451 Assert.fail("Unable to create LSParser!"); 452 } 453 // set filter 454 parser.setFilter(new LSParserFilter() { 455 public short startElement(Element elt) { 456 if (elt.getTagName().equals("ELEMENT1")) { 457 return FILTER_SKIP; 458 } 459 return FILTER_ACCEPT; 460 } 461 462 public short acceptNode(Node enode) { 463 return FILTER_ACCEPT; 464 } 465 466 public int getWhatToShow() { 467 return NodeFilter.SHOW_ALL; 468 } 469 }); 470 String expected = "<?xml version=\"1.0\"?><ROOT><CHILD1/><CHILD1><COC1/></CHILD1><ELEMENT2>test1<CHILD2/></ELEMENT2></ROOT>"; 471 Document doc = parser.parse(getXmlSource(xml1)); 472 if (!match(expected, doc)) { 473 Assert.fail("DOM structure after parsing is not equal to a structure of XML document, that being parsed"); 474 } 475 System.out.println("OKAY"); 476 } 477 478 /** 479 * Equivalence class partitioning with state, input and output values 480 * orientation for public Document parse(LSInput is), <br> 481 * <b>pre-conditions</b>: set filter that SKIPs ELEMENT1 start element, <br> 482 * <b>is</b>: xml1 <br> 483 * <b>output</b>: XML document with ELEMENT1 only. 484 */ 485 @Test 486 public void testFilter0009() { 487 LSParser parser = createLSParser(); 488 if (parser == null) { 489 Assert.fail("Unable to create LSParser!"); 490 } 491 // set filter 492 parser.setFilter(new LSParserFilter() { 493 public short startElement(Element elt) { 494 if (elt.getTagName().startsWith("ELEMENT2")) { 495 return FILTER_INTERRUPT; 496 } 497 return FILTER_ACCEPT; 498 } 499 500 public short acceptNode(Node enode) { 501 return FILTER_ACCEPT; 502 } 503 504 public int getWhatToShow() { 505 return NodeFilter.SHOW_ALL; 506 } 507 }); 508 String expected = "<ROOT><ELEMENT1><CHILD1/><CHILD1><COC1/></CHILD1></ELEMENT1></ROOT>"; 509 Document doc = parser.parse(getXmlSource(xml1)); 510 if (!match(expected, doc)) { 511 Assert.fail("DOM structure after parsing is not equal to a structure of XML document, that being parsed"); 512 } 513 System.out.println("OKAY"); 514 } 515 516 /** 517 * Equivalence class partitioning with state, input and output values 518 * orientation for public Document parse(LSInput is), <br> 519 * <b>pre-conditions</b>: set filter that REJECTs all start element, <br> 520 * <b>is</b>: xml1 <br> 521 * <b>output</b>: empty XML document. 522 */ 523 @Test 524 public void testFilter0010() { 525 LSParser parser = createLSParser(); 526 if (parser == null) { 527 Assert.fail("Unable to create LSParser"); 528 } 529 // set filter 530 parser.setFilter(new LSParserFilter() { 531 public short startElement(Element elt) { 532 return FILTER_REJECT; 533 } 534 535 public short acceptNode(Node enode) { 536 return FILTER_ACCEPT; 537 } 538 539 public int getWhatToShow() { 540 return NodeFilter.SHOW_ALL; 541 } 542 }); 543 Document doc = parser.parse(getXmlSource(xml1)); 544 NodeList children = doc.getDocumentElement().getChildNodes(); 545 if (children.getLength() != 0) { 546 Assert.fail("Not all children skipped"); 547 } 548 System.out.println("OKAY"); 549 } 550 551 /** 552 * Equivalence class partitioning with state, input and output values 553 * orientation for public Document parse(LSInput is), <br> 554 * <b>pre-conditions</b>: set filter that SKIPs all, <br> 555 * <b>is</b>: xml1 <br> 556 * <b>output</b>: empty XML document. 557 */ 558 @Test 559 public void testFilter0011() { 560 LSParser parser = createLSParser(); 561 if (parser == null) { 562 Assert.fail("Unable to create LSParser"); 563 } 564 // set filter 565 parser.setFilter(new LSParserFilter() { 566 public short startElement(Element elt) { 567 return FILTER_SKIP; 568 } 569 570 public short acceptNode(Node enode) { 571 return FILTER_ACCEPT; 572 } 573 574 public int getWhatToShow() { 575 return NodeFilter.SHOW_ALL; 576 } 577 }); 578 Document doc = parser.parse(getXmlSource(xml1)); 579 NodeList children = doc.getDocumentElement().getChildNodes(); 580 if (children.getLength() != 1) { 581 Assert.fail("Not all Element nodes skipped"); 582 } 583 System.out.println("OKAY"); 584 } 585 586 } 587