1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 /* 19 * $Id$ 20 */ 21 22 /* 23 * 24 * SmoketestOuttakes.java 25 * 26 */ 27 package org.apache.qetest.xalanj2; 28 29 // Support for test reporting and harness classes 30 import java.io.File; 31 import java.io.FileOutputStream; 32 import java.io.IOException; 33 import java.util.Properties; 34 35 import javax.xml.parsers.DocumentBuilder; 36 import javax.xml.parsers.DocumentBuilderFactory; 37 import javax.xml.parsers.ParserConfigurationException; 38 import javax.xml.parsers.SAXParser; 39 import javax.xml.parsers.SAXParserFactory; 40 import javax.xml.transform.OutputKeys; 41 import javax.xml.transform.Result; 42 import javax.xml.transform.Templates; 43 import javax.xml.transform.Transformer; 44 import javax.xml.transform.TransformerConfigurationException; 45 import javax.xml.transform.TransformerException; 46 import javax.xml.transform.TransformerFactory; 47 import javax.xml.transform.dom.DOMResult; 48 import javax.xml.transform.dom.DOMSource; 49 import javax.xml.transform.sax.SAXResult; 50 import javax.xml.transform.sax.SAXSource; 51 import javax.xml.transform.sax.SAXTransformerFactory; 52 import javax.xml.transform.sax.TransformerHandler; 53 import javax.xml.transform.stream.StreamResult; 54 import javax.xml.transform.stream.StreamSource; 55 56 import org.apache.qetest.FileBasedTest; 57 import org.apache.qetest.Logger; 58 import org.apache.qetest.OutputNameManager; 59 import org.apache.qetest.QetestUtils; 60 import org.apache.qetest.trax.LoggingErrorListener; 61 import org.apache.qetest.trax.LoggingURIResolver; 62 import org.apache.qetest.xsl.LoggingSAXErrorHandler; 63 import org.apache.qetest.xsl.XSLTestfileInfo; 64 import org.apache.xml.serializer.OutputPropertiesFactory; 65 import org.apache.xml.serializer.Serializer; 66 import org.apache.xml.serializer.SerializerFactory; 67 import org.w3c.dom.Document; 68 import org.w3c.dom.DocumentFragment; 69 import org.w3c.dom.Element; 70 import org.w3c.dom.Node; 71 import org.xml.sax.InputSource; 72 import org.xml.sax.SAXException; 73 import org.xml.sax.XMLReader; 74 75 //------------------------------------------------------------------------- 76 77 /** 78 * Individual test points taken out of other automation files. 79 * 80 * Although as a quality engineer I'm not sure I really like this 81 * idea, I'm temporarily moving test points with known and reported 82 * fail conditions out of a number of other automated tests into 83 * here. In a distributed open source project like this, this 84 * should make it easier for developers to run a reliable smoketest 85 * before making any checkins (since the list of smoketest files 86 * will generally be kept to tests that we expect should pass; thus 87 * any fails when you run the smoketest when you run it are likely 88 * due to recent changes you have made). 89 * 90 * @author shane_curcuru@lotus.com 91 * @version $Id$ 92 */ 93 public class SmoketestOuttakes extends FileBasedTest 94 { 95 96 /** Provides nextName(), currentName() functionality. */ 97 protected OutputNameManager outNames; 98 99 100 /** Just initialize test name, comment, numTestCases. */ SmoketestOuttakes()101 public SmoketestOuttakes() 102 { 103 numTestCases = 6; // REPLACE_num 104 testName = "SmoketestOuttakes"; 105 testComment = "Individual test points taken out of other automation files"; 106 } 107 108 109 /** 110 * Initialize this test - Set names of xml/xsl test files. 111 * 112 * @param p Properties to initialize from (if needed) 113 * @return false if we should abort the test; true otherwise 114 */ doTestFileInit(Properties p)115 public boolean doTestFileInit(Properties p) 116 { 117 // Used for all tests; just dump files in trax subdir 118 File outSubDir = new File(outputDir + File.separator + "trax"); 119 if (!outSubDir.mkdirs()) 120 reporter.logWarningMsg("Could not create output dir: " + outSubDir); 121 // Initialize an output name manager to that dir with .out extension 122 outNames = new OutputNameManager(outputDir + File.separator + "trax" + File.separator 123 + testName, ".out"); 124 125 return true; 126 } 127 128 129 /** 130 * Recreate ExamplesTest.exampleContentHandlerToContentHandler. 131 * 132 * @return false if we should abort the test; true otherwise 133 */ testCase1()134 public boolean testCase1() 135 { 136 reporter.testCaseInit("Recreate ExamplesTest.exampleContentHandlerToContentHandler"); 137 138 try 139 { 140 String xslID = inputDir 141 + File.separator 142 + "trax" 143 + File.separator 144 + "xsl" 145 + File.separator 146 + "foo.xsl"; 147 String sourceID = inputDir 148 + File.separator 149 + "trax" 150 + File.separator 151 + "xml" 152 + File.separator 153 + "foo.xml"; 154 String goldName = goldDir 155 + File.separator 156 + "trax" 157 + File.separator 158 + "ExamplesTest_7.out"; 159 160 reporter.logTraceMsg("NOTE! This file is very sensitive to pathing issues!"); 161 162 TransformerFactory tfactory = TransformerFactory.newInstance(); 163 164 // Does this factory support SAX features? 165 if (!tfactory.getFeature(SAXSource.FEATURE)) 166 { 167 reporter.logErrorMsg("exampleContentHandlerToContentHandler:Processor does not support SAX"); 168 return true; 169 } 170 // If so, we can safely cast. 171 SAXTransformerFactory stfactory = ((SAXTransformerFactory) tfactory); 172 173 // A TransformerHandler is a ContentHandler that will listen for 174 // SAX events, and transform them to the result. 175 reporter.logTraceMsg("newTransformerHandler(new StreamSource(" + QetestUtils.filenameToURL(xslID)); 176 TransformerHandler handler 177 = stfactory.newTransformerHandler(new StreamSource(QetestUtils.filenameToURL(xslID))); 178 179 // Set the result handling to be a serialization to the file output stream. 180 Serializer serializer = SerializerFactory.getSerializer 181 (OutputPropertiesFactory.getDefaultMethodProperties("xml")); 182 FileOutputStream fos = new FileOutputStream(outNames.nextName()); 183 serializer.setOutputStream(fos); 184 reporter.logStatusMsg("Test-output-to: new FileOutputStream(" + outNames.currentName()); 185 186 Result result = new SAXResult(serializer.asContentHandler()); 187 188 handler.setResult(result); 189 190 // Create a reader, and set it's content handler to be the TransformerHandler. 191 XMLReader reader=null; 192 193 // Use JAXP1.1 ( if possible ) 194 try { 195 javax.xml.parsers.SAXParserFactory factory= 196 javax.xml.parsers.SAXParserFactory.newInstance(); 197 factory.setNamespaceAware( true ); 198 javax.xml.parsers.SAXParser jaxpParser= 199 factory.newSAXParser(); 200 reader=jaxpParser.getXMLReader(); 201 202 } catch( javax.xml.parsers.ParserConfigurationException ex ) { 203 throw new org.xml.sax.SAXException( ex ); 204 } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) { 205 throw new org.xml.sax.SAXException( ex1.toString() ); 206 } catch( NoSuchMethodError ex2 ) { 207 } 208 if( reader==null ) reader = getJAXPXMLReader(); 209 reader.setContentHandler(handler); 210 211 // It's a good idea for the parser to send lexical events. 212 // The TransformerHandler is also a LexicalHandler. 213 reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); 214 215 // Parse the source XML, and send the parse events to the TransformerHandler. 216 reporter.logTraceMsg("reader.parse(" + QetestUtils.filenameToURL(sourceID)); 217 reader.parse(QetestUtils.filenameToURL(sourceID)); 218 fos.close(); 219 220 reporter.logTraceMsg("Note: See SPR SCUU4RZT78 for discussion as to why this output is different than XMLReader/XMLFilter"); 221 fileChecker.check(reporter, new File(outNames.currentName()), 222 new File(goldName), 223 "exampleContentHandlerToContentHandler fileChecker of:" + outNames.currentName()); 224 225 226 } 227 catch (Throwable t) 228 { 229 reporter.checkFail("Problem with testCase1:"); 230 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with testCase1"); 231 } 232 reporter.testCaseClose(); 233 return true; 234 } 235 236 237 238 /** 239 * Recreate ExamplesTest.exampleContentHandlerToContentHandler. 240 * 241 * @return false if we should abort the test; true otherwise 242 */ testCase2()243 public boolean testCase2() 244 { 245 reporter.testCaseInit("Recreate ExamplesTest.exampleContentHandlerToContentHandler"); 246 247 String xslID = inputDir 248 + File.separator 249 + "trax" 250 + File.separator 251 + "xsl" 252 + File.separator 253 + "foo.xsl"; 254 String sourceID = inputDir 255 + File.separator 256 + "trax" 257 + File.separator 258 + "xml" 259 + File.separator 260 + "foo.xml"; 261 String goldName = goldDir 262 + File.separator 263 + "trax" 264 + File.separator 265 + "ExamplesTest_18.out"; 266 267 try 268 { 269 270 TransformerFactory tfactory = TransformerFactory.newInstance(); 271 272 // Make sure the transformer factory we obtained supports both 273 // DOM and SAX. 274 if (!(tfactory.getFeature(SAXSource.FEATURE) 275 && tfactory.getFeature(DOMSource.FEATURE))) 276 { 277 reporter.logErrorMsg("exampleContentHandler2DOM:Processor does not support SAX/DOM"); 278 return true; 279 } 280 // We can now safely cast to a SAXTransformerFactory. 281 SAXTransformerFactory sfactory = (SAXTransformerFactory) tfactory; 282 283 // Create an Document node as the root for the output. 284 DocumentBuilderFactory dfactory 285 = DocumentBuilderFactory.newInstance(); 286 DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); 287 org.w3c.dom.Document outNode = docBuilder.newDocument(); 288 289 // Create a ContentHandler that can liston to SAX events 290 // and transform the output to DOM nodes. 291 reporter.logTraceMsg("newTransformerHandler(new StreamSource(" + QetestUtils.filenameToURL(xslID)); 292 TransformerHandler handler 293 = sfactory.newTransformerHandler(new StreamSource(QetestUtils.filenameToURL(xslID))); 294 handler.setResult(new DOMResult(outNode)); 295 296 // Create a reader and set it's ContentHandler to be the 297 // transformer. 298 XMLReader reader=null; 299 300 // Use JAXP1.1 ( if possible ) 301 try { 302 javax.xml.parsers.SAXParserFactory factory= 303 javax.xml.parsers.SAXParserFactory.newInstance(); 304 factory.setNamespaceAware( true ); 305 javax.xml.parsers.SAXParser jaxpParser= 306 factory.newSAXParser(); 307 reader=jaxpParser.getXMLReader(); 308 309 } catch( javax.xml.parsers.ParserConfigurationException ex ) { 310 throw new org.xml.sax.SAXException( ex ); 311 } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) { 312 throw new org.xml.sax.SAXException( ex1.toString() ); 313 } catch( NoSuchMethodError ex2 ) { 314 } 315 if( reader==null ) reader= getJAXPXMLReader(); 316 reader.setContentHandler(handler); 317 reader.setProperty("http://xml.org/sax/properties/lexical-handler", 318 handler); 319 320 // Send the SAX events from the parser to the transformer, 321 // and thus to the DOM tree. 322 reporter.logTraceMsg("reader.parse(" + QetestUtils.filenameToURL(sourceID)); 323 reader.parse(QetestUtils.filenameToURL(sourceID)); 324 325 // Serialize the node for diagnosis. 326 // This serializes to outNames.nextName() 327 exampleSerializeNode(outNode); 328 329 fileChecker.check(reporter, new File(outNames.currentName()), 330 new File(goldName), 331 "exampleContentHandler2DOM fileChecker of:" + outNames.currentName()); 332 333 } 334 catch (Throwable t) 335 { 336 reporter.checkFail("Problem with testCase2:"); 337 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with testCase2"); 338 } 339 reporter.testCaseClose(); 340 return true; 341 } 342 343 344 /** 345 * Serialize a node to System.out; 346 * used in ExamplesTest; testCase1, testCase2 above 347 */ exampleSerializeNode(Node node)348 public void exampleSerializeNode(Node node) 349 throws TransformerException, TransformerConfigurationException, 350 SAXException, IOException, ParserConfigurationException 351 { 352 TransformerFactory tfactory = TransformerFactory.newInstance(); 353 354 // This creates a transformer that does a simple identity transform, 355 // and thus can be used for all intents and purposes as a serializer. 356 Transformer serializer = tfactory.newTransformer(); 357 358 serializer.setOutputProperty(OutputKeys.INDENT, "yes"); 359 serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 360 serializer.transform(new DOMSource(node), 361 new StreamResult(outNames.nextName())); 362 reporter.logStatusMsg("Test-output-to: new StreamResult(" + outNames.currentName()); 363 // TEST UPDATE - Caller must validate outNames.currentName() 364 } 365 366 367 /** 368 * From ErrorListenerTest.java testCase2 369 * Build a bad stylesheet/do a transform with SAX. 370 * Verify that the ErrorListener is called properly. 371 * Primarily using SAXSources. 372 * @return false if we should abort the test; true otherwise 373 */ testCase3()374 public boolean testCase3() 375 { 376 reporter.testCaseInit("Build a bad stylesheet/do a transform with SAX"); 377 XSLTestfileInfo testFileInfo = new XSLTestfileInfo(); 378 testFileInfo.inputName = inputDir 379 + File.separator 380 + "err" 381 + File.separator + "ErrorListenerTest.xsl"; 382 testFileInfo.xmlName = inputDir 383 + File.separator 384 + "err" 385 + File.separator + "ErrorListenerTest.xml"; 386 testFileInfo.goldName = goldDir 387 + File.separator 388 + "err" 389 + File.separator + "ErrorListenerTest.out"; 390 int templatesExpectedType = LoggingErrorListener.TYPE_FATALERROR; 391 String templatesExpectedValue = "decimal-format names must be unique. Name \"myminus\" has been duplicated"; 392 int transformExpectedType = LoggingErrorListener.TYPE_WARNING; 393 String transformExpectedValue = "ExpectedMessage from:list1"; 394 395 396 LoggingErrorListener loggingErrorListener = new LoggingErrorListener(reporter); 397 loggingErrorListener.setThrowWhen(LoggingErrorListener.THROW_NEVER); 398 reporter.logTraceMsg("loggingErrorListener originally setup:" + loggingErrorListener.getQuickCounters()); 399 400 TransformerFactory factory = null; 401 SAXTransformerFactory saxFactory = null; 402 XMLReader reader = null; 403 Templates templates = null; 404 Transformer transformer = null; 405 TransformerHandler handler = null; 406 try 407 { 408 factory = TransformerFactory.newInstance(); 409 saxFactory = (SAXTransformerFactory)factory; // assumes SAXSource.feature! 410 411 // Set the errorListener and validate it 412 saxFactory.setErrorListener(loggingErrorListener); 413 reporter.check((saxFactory.getErrorListener() == loggingErrorListener), 414 true, "set/getErrorListener on saxFactory"); 415 416 // Use the JAXP way to get an XMLReader 417 reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); 418 InputSource is = new InputSource(QetestUtils.filenameToURL(testFileInfo.inputName)); 419 420 // Attempt to build templates from known-bad stylesheet 421 // Validate known errors in stylesheet building 422 loggingErrorListener.setExpected(templatesExpectedType, 423 templatesExpectedValue); 424 reporter.logTraceMsg("About to factory.newTransformerHandler(SAX:" + QetestUtils.filenameToURL(testFileInfo.inputName) + ")"); 425 handler = saxFactory.newTransformerHandler(new SAXSource(is)); 426 reporter.logTraceMsg("loggingErrorListener after newTransformerHandler:" + loggingErrorListener.getQuickCounters()); 427 // Clear out any setExpected or counters 428 loggingErrorListener.reset(); 429 reporter.checkPass("set ErrorListener prevented any exceptions in newTransformerHandler()"); 430 431 // This stylesheet will still work, even though errors 432 // were detected during it's building. Note that 433 // future versions of Xalan or other processors may 434 // not be able to continue here... 435 436 // Create a result and setup SAX parsing 'tree' 437 Result result = new StreamResult(outNames.nextName()); 438 handler.setResult(result); 439 reader.setContentHandler(handler); 440 441 LoggingSAXErrorHandler loggingSAXErrorHandler = new LoggingSAXErrorHandler(reporter); 442 loggingSAXErrorHandler.setThrowWhen(LoggingSAXErrorHandler.THROW_NEVER); 443 reporter.logTraceMsg("LoggingSAXErrorHandler originally setup:" + loggingSAXErrorHandler.getQuickCounters()); 444 reader.setErrorHandler(loggingSAXErrorHandler); 445 446 // Validate the first xsl:message call in the stylesheet 447 loggingErrorListener.setExpected(transformExpectedType, 448 transformExpectedValue); 449 reporter.logInfoMsg("about to parse/transform(" + QetestUtils.filenameToURL(testFileInfo.xmlName) + ")"); 450 reader.parse(QetestUtils.filenameToURL(testFileInfo.xmlName)); 451 reporter.logTraceMsg("LoggingSAXErrorHandler after parse:" + loggingSAXErrorHandler.getQuickCounters()); 452 // Clear out any setExpected or counters 453 loggingErrorListener.reset(); 454 loggingSAXErrorHandler.reset(); 455 456 // Validate the actual output file as well: in this case, 457 // the stylesheet should still work 458 fileChecker.check(reporter, 459 new File(outNames.currentName()), 460 new File(testFileInfo.goldName), 461 "Bugzilla#4044 SAX transform of error xsl into: " + outNames.currentName()); 462 } 463 catch (Throwable t) 464 { 465 reporter.checkFail("errorListener-SAX unexpectedly threw: " + t.toString()); 466 reporter.logThrowable(Logger.ERRORMSG, t, "errorListener-SAX unexpectedly threw"); 467 } 468 469 reporter.testCaseClose(); 470 return true; 471 } 472 473 474 /** 475 * From ErrorListenerTest.java testCase3 476 * Build a bad stylesheet/do a transform with DOMs. 477 * Verify that the ErrorListener is called properly. 478 * Primarily using DOMSources. 479 * @return false if we should abort the test; true otherwise 480 */ testCase4()481 public boolean testCase4() 482 { 483 reporter.testCaseInit("Build a bad stylesheet/do a transform with DOMs"); 484 XSLTestfileInfo testFileInfo = new XSLTestfileInfo(); 485 testFileInfo.inputName = inputDir 486 + File.separator 487 + "err" 488 + File.separator + "ErrorListenerTest.xsl"; 489 testFileInfo.xmlName = inputDir 490 + File.separator 491 + "err" 492 + File.separator + "ErrorListenerTest.xml"; 493 testFileInfo.goldName = goldDir 494 + File.separator 495 + "err" 496 + File.separator + "ErrorListenerTest.out"; 497 int templatesExpectedType = LoggingErrorListener.TYPE_FATALERROR; 498 String templatesExpectedValue = "decimal-format names must be unique. Name \"myminus\" has been duplicated"; 499 int transformExpectedType = LoggingErrorListener.TYPE_WARNING; 500 String transformExpectedValue = "ExpectedMessage from:list1"; 501 502 LoggingErrorListener loggingErrorListener = new LoggingErrorListener(reporter); 503 loggingErrorListener.setThrowWhen(LoggingErrorListener.THROW_NEVER); 504 reporter.logTraceMsg("loggingErrorListener originally setup:" + loggingErrorListener.getQuickCounters()); 505 506 TransformerFactory factory = null; 507 Templates templates = null; 508 Transformer transformer = null; 509 DocumentBuilderFactory dfactory = null; 510 DocumentBuilder docBuilder = null; 511 Node xmlNode = null; 512 Node xslNode = null; 513 try 514 { 515 // Startup a DOM factory, create some nodes/DOMs 516 dfactory = DocumentBuilderFactory.newInstance(); 517 dfactory.setNamespaceAware(true); 518 docBuilder = dfactory.newDocumentBuilder(); 519 reporter.logInfoMsg("parsing xml, xsl files to DOMs"); 520 xslNode = docBuilder.parse(new InputSource(QetestUtils.filenameToURL(testFileInfo.inputName))); 521 xmlNode = docBuilder.parse(new InputSource(QetestUtils.filenameToURL(testFileInfo.xmlName))); 522 523 // Create a transformer factory with an error listener 524 factory = TransformerFactory.newInstance(); 525 factory.setErrorListener(loggingErrorListener); 526 527 // Attempt to build templates from known-bad stylesheet 528 // Validate known errors in stylesheet building 529 loggingErrorListener.setExpected(templatesExpectedType, 530 templatesExpectedValue); 531 reporter.logTraceMsg("About to factory.newTemplates(DOM:" + QetestUtils.filenameToURL(testFileInfo.inputName) + ")"); 532 templates = factory.newTemplates(new DOMSource(xslNode)); 533 reporter.logTraceMsg("loggingErrorListener after newTemplates:" + loggingErrorListener.getQuickCounters()); 534 // Clear out any setExpected or counters 535 loggingErrorListener.reset(); 536 reporter.checkPass("set ErrorListener prevented any exceptions in newTemplates()"); 537 538 // This stylesheet will still work, even though errors 539 // were detected during it's building. Note that 540 // future versions of Xalan or other processors may 541 // not be able to continue here... 542 reporter.logErrorMsg("Bugzilla#1062 throws NPE below at templates.newTransformer()"); 543 transformer = templates.newTransformer(); 544 545 reporter.logTraceMsg("default transformer's getErrorListener is: " + transformer.getErrorListener()); 546 // Set the errorListener and validate it 547 transformer.setErrorListener(loggingErrorListener); 548 reporter.check((transformer.getErrorListener() == loggingErrorListener), 549 true, "set/getErrorListener on transformer"); 550 551 // Validate the first xsl:message call in the stylesheet 552 loggingErrorListener.setExpected(transformExpectedType, 553 transformExpectedValue); 554 reporter.logInfoMsg("about to transform(DOM, StreamResult)"); 555 transformer.transform(new DOMSource(xmlNode), 556 new StreamResult(outNames.nextName())); 557 reporter.logTraceMsg("after transform(...)"); 558 // Clear out any setExpected or counters 559 loggingErrorListener.reset(); 560 561 // Validate the actual output file as well: in this case, 562 // the stylesheet should still work 563 fileChecker.check(reporter, 564 new File(outNames.currentName()), 565 new File(testFileInfo.goldName), 566 "DOM transform of error xsl into: " + outNames.currentName()); 567 568 } 569 catch (Throwable t) 570 { 571 reporter.checkFail("errorListener-DOM unexpectedly threw: " + t.toString()); 572 reporter.logThrowable(Logger.ERRORMSG, t, "errorListener-DOM unexpectedly threw"); 573 } 574 575 reporter.testCaseClose(); 576 return true; 577 } 578 579 580 /** 581 * From URIResolverTest.java testCase1 582 * Build a stylesheet/do a transform with lots of URIs to resolve. 583 * Verify that the URIResolver is called properly. 584 * @return false if we should abort the test; true otherwise 585 */ testCase5()586 public boolean testCase5() 587 { 588 reporter.testCaseInit("Build a stylesheet/do a transform with lots of URIs to resolve"); 589 590 XSLTestfileInfo testFileInfo = new XSLTestfileInfo(); 591 testFileInfo.inputName = inputDir + File.separator + "trax" + File.separator + "URIResolverTest.xsl"; 592 testFileInfo.xmlName = inputDir + File.separator + "trax" + File.separator + "URIResolverTest.xml"; 593 testFileInfo.goldName = goldDir + File.separator + "trax" + File.separator + "URIResolverTest.out"; 594 595 TransformerFactory factory = null; 596 Templates templates = null; 597 Transformer transformer = null; 598 try 599 { 600 factory = TransformerFactory.newInstance(); 601 // Set the URIResolver and validate it 602 reporter.logInfoMsg("About to factory.newTemplates(" + QetestUtils.filenameToURL(testFileInfo.inputName) + ")"); 603 templates = factory.newTemplates(new StreamSource(QetestUtils.filenameToURL(testFileInfo.inputName))); 604 transformer = templates.newTransformer(); 605 606 // Set the URIResolver and validate it 607 LoggingURIResolver loggingURIResolver = new LoggingURIResolver((Logger)reporter); 608 reporter.logTraceMsg("loggingURIResolver originally setup:" + loggingURIResolver.getQuickCounters()); 609 transformer.setURIResolver(loggingURIResolver); 610 reporter.check((transformer.getURIResolver() == loggingURIResolver), 611 true, "set/getURIResolver on transformer"); 612 613 // Validate various URI's to be resolved during transform 614 // time with the loggingURIResolver 615 reporter.logWarningMsg("Bugzilla#2425 every document() call is resolved twice twice - two fails caused below"); 616 String[] expectedXmlUris = 617 { 618 "{" + QetestUtils.filenameToURL(testFileInfo.inputName) + "}" + "../impincl/SystemIdImport.xsl", 619 "{" + QetestUtils.filenameToURL(testFileInfo.inputName) + "}" + "impincl/SystemIdImport.xsl", 620 "{" + QetestUtils.filenameToURL(testFileInfo.inputName) + "}" + "systemid/impincl/SystemIdImport.xsl", 621 }; 622 loggingURIResolver.setExpected(expectedXmlUris); 623 reporter.logTraceMsg("about to transform(...)"); 624 transformer.transform(new StreamSource(QetestUtils.filenameToURL(testFileInfo.xmlName)), 625 new StreamResult(outNames.nextName())); 626 reporter.logTraceMsg("after transform(...)"); 627 } 628 catch (Throwable t) 629 { 630 reporter.checkFail("URIResolver test unexpectedly threw: " + t.toString()); 631 reporter.logThrowable(Logger.ERRORMSG, t, "URIResolver test unexpectedly threw"); 632 } 633 634 reporter.testCaseClose(); 635 return true; 636 } 637 638 639 public static final String xslNamespace = "http://www.w3.org/1999/XSL/Transform"; 640 public static final String nsNamespace = "http://www.w3.org/XML/1998/namespace"; 641 /** 642 * From ProgrammaticDOMTest.java testCase2 Bugzilla#5133 643 * Build a stylesheet DOM programmatically and use it. 644 * 645 * @return false if we should abort the test; true otherwise 646 */ testCase6()647 public boolean testCase6() 648 { 649 reporter.testCaseInit("Build a stylesheet DOM programmatically and use it"); 650 651 XSLTestfileInfo testFileInfo = new XSLTestfileInfo(); 652 testFileInfo.inputName = inputDir + File.separator + "trax" + File.separator + "identity.xsl"; 653 testFileInfo.xmlName = inputDir + File.separator + "trax" + File.separator + "identity.xml"; 654 testFileInfo.goldName = goldDir + File.separator + "trax" + File.separator + "identity.out"; 655 try 656 { 657 // Startup a factory and docbuilder, create some nodes/DOMs 658 DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 659 dfactory.setNamespaceAware(true); 660 DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); 661 662 reporter.logTraceMsg("parsing xml file"); 663 Document xmlDoc = docBuilder.parse(new InputSource(testFileInfo.xmlName)); 664 TransformerFactory factory = TransformerFactory.newInstance(); 665 Transformer transformer = null; 666 667 // Programmatically build the XSL file into a Document and transform 668 Document xslBuiltDoc = docBuilder.newDocument(); 669 appendIdentityDOMXSL(xslBuiltDoc, xslBuiltDoc, true); 670 // For debugging, write the generated stylesheet out 671 // Note this will not textually exactly match the identity.xsl file 672 reporter.logInfoMsg("Writing out xslBuiltDoc to "+ outNames.nextName()); 673 transformer = factory.newTransformer(); 674 transformer.transform(new DOMSource(xslBuiltDoc), new StreamResult(outNames.currentName())); 675 676 reporter.logInfoMsg("About to newTransformer(xslBuiltDoc)"); 677 transformer = factory.newTransformer(new DOMSource(xslBuiltDoc)); 678 reporter.logInfoMsg("About to transform(xmlDoc, StreamResult(" + outNames.nextName() + "))"); 679 transformer.transform(new DOMSource(xmlDoc), new StreamResult(outNames.currentName())); 680 fileChecker.check(reporter, 681 new File(outNames.currentName()), 682 new File(testFileInfo.goldName), 683 "transform(xslBuiltDoc,...) into " + outNames.currentName()); 684 685 686 // Programmatically build the XSL file into a DocFrag and transform 687 xslBuiltDoc = docBuilder.newDocument(); 688 DocumentFragment xslBuiltDocFrag = xslBuiltDoc.createDocumentFragment(); 689 appendIdentityDOMXSL(xslBuiltDocFrag, xslBuiltDoc, true); 690 // For debugging, write the generated stylesheet out 691 reporter.logInfoMsg("Writing out xslBuiltDocFrag to "+ outNames.nextName()); 692 transformer = factory.newTransformer(); 693 transformer.transform(new DOMSource(xslBuiltDocFrag), new StreamResult(outNames.currentName())); 694 695 reporter.logCriticalMsg("//@todo Verify that this is even a valid operation!"); 696 reporter.logInfoMsg("About to newTransformer(xslBuiltDocFrag)"); 697 reporter.logCriticalMsg("Bugzilla#5133: will throw NPE"); 698 transformer = factory.newTransformer(new DOMSource(xslBuiltDocFrag)); 699 reporter.logInfoMsg("About to transform(xmlDoc, StreamResult(" + outNames.nextName() + "))"); 700 transformer.transform(new DOMSource(xmlDoc), new StreamResult(outNames.currentName())); 701 fileChecker.check(reporter, 702 new File(outNames.currentName()), 703 new File(testFileInfo.goldName), 704 "transform(xslBuiltDocFrag,...) into " + outNames.currentName()); 705 } 706 catch (Throwable t) 707 { 708 reporter.checkFail("Problem with various XSL1 elems/documents"); 709 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with various XSL1 elems/documents"); 710 } 711 try 712 { 713 // Startup a factory and docbuilder, create some nodes/DOMs 714 DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 715 dfactory.setNamespaceAware(true); 716 DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); 717 718 reporter.logTraceMsg("parsing xml file"); 719 Document xmlDoc = docBuilder.parse(new InputSource(testFileInfo.xmlName)); 720 TransformerFactory factory = TransformerFactory.newInstance(); 721 Transformer transformer = null; 722 723 // Programmatically build the XSL file into an Element and transform 724 Document xslBuiltDoc = docBuilder.newDocument(); 725 // Note: Here, we implicitly already have the outer list 726 // element, so ensure the worker method doesn't add again 727 reporter.logCriticalMsg("Bugzilla#5133: will throw DOM003 exception"); 728 Element xslBuiltElem = xslBuiltDoc.createElementNS(xslNamespace, "xsl:stylesheet"); 729 xslBuiltElem.setAttributeNS(null, "version", "1.0"); 730 appendIdentityDOMXSL(xslBuiltElem, xslBuiltDoc, false); 731 // For debugging, write the generated stylesheet out 732 reporter.logInfoMsg("Writing out xslBuiltElem to "+ outNames.nextName()); 733 transformer = factory.newTransformer(); 734 transformer.transform(new DOMSource(xslBuiltElem), new StreamResult(outNames.currentName())); 735 736 reporter.logCriticalMsg("//@todo Verify that this is even a valid operation!"); 737 reporter.logInfoMsg("About to newTransformer(xslBuiltElem)"); 738 transformer = factory.newTransformer(new DOMSource(xslBuiltElem)); 739 reporter.logInfoMsg("About to transform(xmlDoc, StreamResult(" + outNames.nextName() + "))"); 740 transformer.transform(new DOMSource(xmlDoc), new StreamResult(outNames.currentName())); 741 fileChecker.check(reporter, 742 new File(outNames.currentName()), 743 new File(testFileInfo.goldName), 744 "transform(xslBuiltElem,...) into " + outNames.currentName()); 745 } 746 catch (Throwable t) 747 { 748 reporter.checkFail("Problem with various XSL2 elems/documents"); 749 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with various XSL2 elems/documents"); 750 } 751 752 reporter.testCaseClose(); 753 return true; 754 } 755 756 /** 757 * Adds identity.xsl elems to Node passed in. 758 * Subject to change; hackish for now 759 * @author curcuru 760 * @param n Node to append DOM elems to 761 * @param factory Document providing createElement, etc. services 762 * @param useOuterElem if we should append the top-level <stylesheet> elem 763 */ appendIdentityDOMXSL(Node n, Document factory, boolean useOuterElem)764 public void appendIdentityDOMXSL(Node n, Document factory, boolean useOuterElem) 765 { 766 try 767 { 768 /// <xsl:template match="@*|node()"> 769 Element template = factory.createElementNS(xslNamespace, "xsl:template"); 770 template.setAttributeNS(null, "match", "@*|node()"); 771 772 /// <xsl:copy> 773 Element copyElem = factory.createElementNS(xslNamespace, "xsl:copy"); 774 775 /// <xsl:apply-templates select="@*|node()"/> 776 Element applyTemplatesElem = factory.createElementNS(xslNamespace, "xsl:apply-templates"); 777 applyTemplatesElem.setAttributeNS(null, "select", "@*|node()"); 778 779 // Stick it all together with faked-up newlines for readability 780 copyElem.appendChild(factory.createTextNode("\n ")); 781 copyElem.appendChild(applyTemplatesElem); 782 copyElem.appendChild(factory.createTextNode("\n ")); 783 784 template.appendChild(factory.createTextNode("\n ")); 785 template.appendChild(copyElem); 786 template.appendChild(factory.createTextNode("\n")); 787 788 789 if (useOuterElem) 790 { 791 // If asked to, create and append top-level <stylesheet> elem 792 /// <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 793 Element stylesheetElem = factory.createElementNS(xslNamespace, "xsl:stylesheet"); 794 stylesheetElem.setAttributeNS(null, "version", "1.0"); 795 796 // Following is not officially needed by the DOM, but may help 797 // less-sophisticated DOM readers downstream 798 // Removed due to DOM003 Namespace error 799 // stylesheetElem.setAttributeNS(nsNamespace, "xmlns:xsl", xslNamespace); 800 stylesheetElem.appendChild(template); 801 n.appendChild(stylesheetElem); 802 } 803 else 804 { 805 // Otherwise, just use their Node 806 n.appendChild(template); 807 } 808 809 } 810 catch (Exception e) 811 { 812 reporter.logErrorMsg("appendIdentityDOMXSL threw: " + e.toString()); 813 reporter.logThrowable(Logger.ERRORMSG, e, "appendIdentityDOMXSL threw"); 814 } 815 } 816 817 /** 818 * Worker method to get an XMLReader. 819 * 820 * Not the most efficient of methods, but makes the code simpler. 821 * 822 * @return a new XMLReader for use, with setNamespaceAware(true) 823 */ getJAXPXMLReader()824 protected XMLReader getJAXPXMLReader() 825 throws Exception 826 { 827 // Be sure to use the JAXP methods only! 828 SAXParserFactory factory = SAXParserFactory.newInstance(); 829 factory.setNamespaceAware(true); 830 SAXParser saxParser = factory.newSAXParser(); 831 return saxParser.getXMLReader(); 832 } 833 834 835 /** 836 * Convenience method to print out usage information - update if needed. 837 * @return String denoting usage of this test class 838 */ usage()839 public String usage() 840 { 841 return ("Common [optional] options supported by SmoketestOuttakes:\n" 842 + "(Note: assumes inputDir=.\\tests\\api)\n" 843 + super.usage()); // Grab our parent classes usage as well 844 } 845 846 847 /** 848 * Main method to run test from the command line - can be left alone. 849 * @param args command line argument array 850 */ main(String[] args)851 public static void main(String[] args) 852 { 853 SmoketestOuttakes app = new SmoketestOuttakes(); 854 app.doMain(args); 855 } 856 } 857