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 * OutputPropertiesTest.java 25 * 26 */ 27 package org.apache.qetest.trax; 28 29 import java.io.File; 30 import java.io.FileInputStream; 31 import java.io.FileOutputStream; 32 import java.util.Enumeration; 33 import java.util.Properties; 34 35 import javax.xml.parsers.DocumentBuilder; 36 import javax.xml.parsers.DocumentBuilderFactory; 37 import javax.xml.transform.Result; 38 import javax.xml.transform.Templates; 39 import javax.xml.transform.Transformer; 40 import javax.xml.transform.TransformerFactory; 41 import javax.xml.transform.dom.DOMSource; 42 import javax.xml.transform.stream.StreamResult; 43 import javax.xml.transform.stream.StreamSource; 44 45 import org.apache.qetest.FileBasedTest; 46 import org.apache.qetest.Logger; 47 import org.apache.qetest.OutputNameManager; 48 import org.apache.qetest.QetestUtils; 49 import org.apache.qetest.xsl.XSLTestfileInfo; 50 import org.w3c.dom.Document; 51 52 //------------------------------------------------------------------------- 53 54 /** 55 * Verify how output properties are handled from stylesheets and the API. 56 * @author shane_curcuru@lotus.com 57 * @author Krishna.Meduri@eng.sun.com 58 * @version $Id$ 59 */ 60 public class OutputPropertiesTest extends FileBasedTest 61 { 62 63 /** Used for generating names of actual output files. */ 64 protected OutputNameManager outNames; 65 66 /** Default OutputPropertiesTest.xml/xsl file pair. */ 67 protected XSLTestfileInfo htmlFileInfo = new XSLTestfileInfo(); 68 69 /** xml/xsl file pair used in testlets. */ 70 protected XSLTestfileInfo testletFileInfo = new XSLTestfileInfo(); 71 72 /** Alternate gold file used in testlets. */ 73 protected String citiesIndentNoGoldFile = null; 74 75 /** Alternate gold file used in testlets. */ 76 protected String citiesMethodTextGoldFile = null; 77 78 /** Subdirectory under test\tests\api for our xsl/xml files. */ 79 public static final String TRAX_SUBDIR = "trax"; 80 81 /** Key for testlets to do special validation. */ 82 public static final String CROSS_VALIDATE = "validate-non-gold"; 83 84 /** Just initialize test name, comment, numTestCases. */ OutputPropertiesTest()85 public OutputPropertiesTest() 86 { 87 numTestCases = 2; // REPLACE_num 88 testName = "OutputPropertiesTest"; 89 testComment = "Verify how output properties are handled from stylesheets and the API"; 90 } 91 92 93 /** 94 * Initialize this test - Set names of xml/xsl test files, etc. 95 * 96 * @param p Properties to initialize from (if needed) 97 * @return false if we should abort the test; true otherwise 98 */ doTestFileInit(Properties p)99 public boolean doTestFileInit(Properties p) 100 { 101 // Used for all tests; just dump files in trax subdir 102 File outSubDir = new File(outputDir + File.separator + TRAX_SUBDIR); 103 if (!outSubDir.mkdirs()) 104 reporter.logWarningMsg("Possible problem creating output dir: " + outSubDir); 105 // Initialize an output name manager to that dir with .out extension 106 outNames = new OutputNameManager(outputDir + File.separator + TRAX_SUBDIR 107 + File.separator + testName, ".out"); 108 109 String testBasePath = inputDir 110 + File.separator 111 + TRAX_SUBDIR 112 + File.separator; 113 String goldBasePath = goldDir 114 + File.separator 115 + TRAX_SUBDIR 116 + File.separator; 117 118 htmlFileInfo.inputName = testBasePath + "OutputPropertiesHTML.xsl"; 119 htmlFileInfo.xmlName = testBasePath + "OutputPropertiesHTML.xml"; 120 htmlFileInfo.goldName = goldBasePath + "OutputPropertiesHTML.out"; 121 122 testletFileInfo.inputName = testBasePath + File.separator + "sax" 123 + File.separator + "cities.xsl"; 124 testletFileInfo.xmlName = testBasePath + File.separator + "sax" 125 + File.separator + "cities.xml"; 126 testletFileInfo.goldName = goldBasePath + File.separator + "sax" 127 + File.separator + "cities.out"; 128 citiesIndentNoGoldFile = goldBasePath + File.separator + "sax" 129 + File.separator + "cities-indent-no.out"; 130 citiesMethodTextGoldFile = goldBasePath + File.separator + "sax" 131 + File.separator + "cities-method-text.out"; 132 return true; 133 } 134 135 136 /** 137 * Verify setting output properties individually or whole blocks. 138 * @return false if we should abort the test; true otherwise 139 */ testCase1()140 public boolean testCase1() 141 { 142 reporter.testCaseInit("Verify setting output properties individually or whole blocks."); 143 // Simply start with Krishna's individual tests 144 testlet0(testletFileInfo.xmlName, testletFileInfo.inputName, testletFileInfo.goldName); 145 testlet1(testletFileInfo.xmlName, testletFileInfo.inputName, citiesIndentNoGoldFile); 146 testlet2(testletFileInfo.xmlName, testletFileInfo.inputName, citiesIndentNoGoldFile); 147 testlet3(testletFileInfo.xmlName, testletFileInfo.inputName, citiesMethodTextGoldFile); 148 149 reporter.testCaseClose(); 150 return true; 151 } 152 153 /** 154 * Verify various output properties with HTML. 155 * @return false if we should abort the test; true otherwise 156 */ testCase2()157 public boolean testCase2() 158 { 159 reporter.testCaseInit("Verify various output properties with HTML."); 160 TransformerFactory factory = null; 161 Templates templates = null; 162 try 163 { 164 // Preprocess the HTML stylesheet for later use 165 factory = TransformerFactory.newInstance(); 166 reporter.logInfoMsg("creating shared newTemplates(" + QetestUtils.filenameToURL(htmlFileInfo.inputName) + ")"); 167 templates = factory.newTemplates(new StreamSource(QetestUtils.filenameToURL(htmlFileInfo.inputName))); 168 reporter.logHashtable(Logger.STATUSMSG, 169 templates.getOutputProperties(), "shared templates output properties"); 170 171 // Process the file once with default properties 172 Transformer transformer = templates.newTransformer(); 173 Result result = new StreamResult(outNames.nextName()); 174 reporter.logInfoMsg("(0)shared transform(" + QetestUtils.filenameToURL(htmlFileInfo.xmlName) 175 + ", " + outNames.currentName() + ")"); 176 transformer.transform(new StreamSource(QetestUtils.filenameToURL(htmlFileInfo.xmlName)), result); 177 // Validate the default transform 178 if 179 (Logger.PASS_RESULT 180 != fileChecker.check(reporter, 181 new File(outNames.currentName()), 182 new File(htmlFileInfo.goldName), 183 "(0)shared transform into: " + outNames.currentName() 184 + " gold: " + htmlFileInfo.goldName) 185 ) 186 { 187 reporter.logInfoMsg("(0)shared transform failure reason:" + fileChecker.getExtendedInfo()); 188 } 189 } 190 catch (Throwable t) 191 { 192 reporter.checkErr("(0)Creating shared stylesheet threw:" + t.toString()); 193 reporter.logThrowable(reporter.ERRORMSG, t, "(0)Creating shared stylesheet threw "); 194 return true; 195 } 196 197 // Create a number of testcases and use worker method to process 198 Properties setProps = new Properties(); 199 // If we reset only one property each time, the results should match 200 // whether we set it thru properties or individually 201 setProps.put("indent", "no"); 202 outputPropertyTestlet(templates, QetestUtils.filenameToURL(htmlFileInfo.xmlName), 203 setProps, CROSS_VALIDATE, CROSS_VALIDATE, 204 "(1)Just reset indent=no"); 205 206 setProps = new Properties(); 207 setProps.put("method", "xml"); 208 outputPropertyTestlet(templates, QetestUtils.filenameToURL(htmlFileInfo.xmlName), 209 setProps, CROSS_VALIDATE, CROSS_VALIDATE, 210 "(2)Just reset method=xml"); 211 212 // Just changing the standalone doesn't affect HTML output 213 setProps = new Properties(); 214 setProps.put("standalone", "no"); 215 outputPropertyTestlet(templates, QetestUtils.filenameToURL(htmlFileInfo.xmlName), 216 setProps, htmlFileInfo.goldName, htmlFileInfo.goldName, 217 "(3)Just reset standalone=no"); 218 reporter.testCaseClose(); 219 return true; 220 } 221 222 /** 223 * outputPropertyTestlet: transform with specifically set output Properties. 224 * Sets properties as a block and also individually, and checks 225 * both outputs against the gold file. 226 * @author shane_curcuru@lotus.com 227 */ outputPropertyTestlet(Templates templates, String xmlId, Properties setProps, String goldName1, String goldName2, String desc)228 public void outputPropertyTestlet(Templates templates, String xmlId, 229 Properties setProps, String goldName1, String goldName2, 230 String desc) 231 { 232 try 233 { 234 reporter.logHashtable(Logger.STATUSMSG, setProps, 235 "(-)" + desc + " begin with properties"); 236 // First, set the properties as a block and transform 237 Transformer transformer1 = templates.newTransformer(); 238 transformer1.setOutputProperties(setProps); 239 Result result1 = new StreamResult(outNames.nextName()); 240 reporter.logTraceMsg("(-a)transform(" + xmlId + ", " + outNames.currentName() + ")"); 241 transformer1.transform(new StreamSource(xmlId), result1); 242 // Only do validation if asked to 243 if (CROSS_VALIDATE == goldName1) 244 { 245 reporter.logWarningMsg("(-a-no-validation)" + desc + " into: " + outNames.currentName()); 246 } 247 else if 248 (Logger.PASS_RESULT 249 != fileChecker.check(reporter, 250 new File(outNames.currentName()), 251 new File(goldName1), 252 "(-a)" + desc + " into: " + outNames.currentName() 253 + " gold: " + goldName1) 254 ) 255 { 256 reporter.logInfoMsg("(-a)" + desc + " failure reason:" + fileChecker.getExtendedInfo()); 257 } 258 259 // Second, set the properties individually and transform 260 Transformer transformer2 = templates.newTransformer(); 261 for (Enumeration names = setProps.propertyNames(); 262 names.hasMoreElements(); /* no increment portion */ ) 263 { 264 String key = (String)names.nextElement(); 265 String value = setProps.getProperty(key); 266 transformer2.setOutputProperty(key, value); 267 } 268 Result result2 = new StreamResult(outNames.nextName()); 269 reporter.logTraceMsg("(-b)transform(" + xmlId + ", " + outNames.currentName() + ")"); 270 transformer2.transform(new StreamSource(xmlId), result2); 271 // Only do validation if asked to 272 // If cross-validating, validate the first file against the second one 273 if (CROSS_VALIDATE == goldName2) 274 { 275 if 276 (Logger.PASS_RESULT 277 != fileChecker.check(reporter, 278 new File(outNames.previousName()), 279 new File(outNames.currentName()), 280 "(-b)" + desc + " into: " + outNames.currentName() 281 + " cross: " + outNames.previousName()) 282 ) 283 { 284 reporter.logInfoMsg("(-b)" + desc + " failure reason:" + fileChecker.getExtendedInfo()); 285 } 286 } 287 else if 288 (Logger.PASS_RESULT 289 != fileChecker.check(reporter, 290 new File(outNames.currentName()), 291 new File(goldName2), 292 "(-b)" + desc + " into: " + outNames.currentName() 293 + " gold: " + goldName2) 294 ) 295 { 296 reporter.logInfoMsg("(-b)" + desc + " failure reason:" + fileChecker.getExtendedInfo()); 297 } 298 } 299 catch (Throwable t) 300 { 301 reporter.checkFail("(-)" + desc + " threw:" + t.toString()); 302 reporter.logThrowable(reporter.ERRORMSG, t, "(-)" + desc + " threw "); 303 } 304 } 305 306 307 /** 308 * testlet0: transform with just stylesheet properties. 309 * @author shane_curcuru@lotus.com 310 */ testlet0(String xmlName, String xslName, String goldName)311 public void testlet0(String xmlName, String xslName, String goldName) 312 { 313 try 314 { 315 reporter.logStatusMsg("testlet0: transform with just stylesheet properties"); 316 317 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 318 dbf.setNamespaceAware(true); // sc for Xerces 319 DocumentBuilder db = dbf.newDocumentBuilder(); 320 reporter.logTraceMsg("docBld.parse(" + xslName + ")"); 321 Document document = db.parse(new File(xslName)); 322 DOMSource domSource = new DOMSource(document); 323 domSource.setSystemId(QetestUtils.filenameToURL(xslName)); // sc 324 325 TransformerFactory tfactory = TransformerFactory.newInstance(); 326 Transformer transformer = tfactory.newTransformer(domSource); 327 Properties xslProps = transformer.getOutputProperties(); 328 reporter.logHashtable(Logger.STATUSMSG, xslProps, 329 "Properties originally from the stylesheet"); 330 331 reporter.logTraceMsg("new StreamSource(new FileInputStream(" + xmlName + "))"); 332 StreamSource streamSource = new StreamSource(new FileInputStream(xmlName)); 333 FileOutputStream fos = new FileOutputStream(outNames.nextName()); 334 StreamResult streamResult = new StreamResult(fos); 335 336 // Verify transform with existing properties 337 reporter.logTraceMsg("transformer.transform(xml, " + outNames.currentName() + ")"); 338 transformer.transform(streamSource, streamResult); 339 fos.close(); 340 341 if (Logger.PASS_RESULT 342 != fileChecker.check(reporter, 343 new File(outNames.currentName()), 344 new File(goldName), 345 "(t0)transform with stylesheet properties into: " + outNames.currentName()) 346 ) 347 { 348 reporter.logInfoMsg("(t0)transform with stylesheet properties failure reason:" + fileChecker.getExtendedInfo()); 349 } 350 } 351 catch (Throwable t) 352 { 353 reporter.checkFail("testlet threw: " + t.toString()); 354 reporter.logThrowable(Logger.WARNINGMSG, t, "testlet threw "); 355 } 356 } 357 /** 358 * testlet1: verify setOutputProperties(Properties). 359 * @author Krishna.Meduri@eng.sun.com 360 */ testlet1(String xmlName, String xslName, String goldName)361 public void testlet1(String xmlName, String xslName, String goldName) 362 { 363 try 364 { 365 reporter.logStatusMsg("testlet1: verify setOutputProperties(Properties)"); 366 367 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 368 dbf.setNamespaceAware(true); // sc for Xerces 369 DocumentBuilder db = dbf.newDocumentBuilder(); 370 reporter.logTraceMsg("docBld.parse(" + xslName + ")"); 371 Document document = db.parse(new File(xslName)); 372 DOMSource domSource = new DOMSource(document); 373 domSource.setSystemId(QetestUtils.filenameToURL(xslName)); // sc 374 375 TransformerFactory tfactory = TransformerFactory.newInstance(); 376 Transformer transformer = tfactory.newTransformer(domSource); 377 Properties xslProps = transformer.getOutputProperties(); 378 reporter.logHashtable(Logger.STATUSMSG, xslProps, 379 "Properties originally from the stylesheet"); 380 381 reporter.logTraceMsg("new StreamSource(new FileInputStream(" + xmlName + "))"); 382 StreamSource streamSource = new StreamSource(new FileInputStream(xmlName)); 383 FileOutputStream fos = new FileOutputStream(outNames.nextName()); 384 StreamResult streamResult = new StreamResult(fos); 385 386 // Verify setting a whole block of properties 387 Properties properties = new Properties(); 388 properties.put("method", "xml"); 389 properties.put("encoding", "UTF-8"); 390 properties.put("omit-xml-declaration", "no"); 391 properties.put("{http://xml.apache.org/xslt}indent-amount", "0"); 392 properties.put("indent", "no"); // This should override the indent=yes in the stylesheet 393 properties.put("standalone", "no"); 394 properties.put("version", "1.0"); 395 properties.put("media-type", "text/xml"); 396 reporter.logHashtable(Logger.STATUSMSG, properties, 397 "Properties block to be set via API"); 398 reporter.logTraceMsg("transformer.setOutputProperties(properties block)"); 399 transformer.setOutputProperties(properties); 400 401 reporter.logTraceMsg("transformer.transform(xml, " + outNames.currentName() + ")"); 402 transformer.transform(streamSource, streamResult); 403 fos.close(); 404 405 if (Logger.PASS_RESULT 406 != fileChecker.check(reporter, 407 new File(outNames.currentName()), 408 new File(goldName), 409 "(t1)transform after setOutputProperties(props) into: " + outNames.currentName()) 410 ) 411 { 412 reporter.logInfoMsg("(t1)transform after setOutputProperties(props) failure reason:" + fileChecker.getExtendedInfo()); 413 } 414 } 415 catch (Throwable t) 416 { 417 reporter.checkFail("testlet threw: " + t.toString()); 418 reporter.logThrowable(Logger.WARNINGMSG, t, "testlet threw "); 419 } 420 } 421 422 /** 423 * testlet2: verify setOutputProperty(s, s). 424 * @author Krishna.Meduri@eng.sun.com 425 */ testlet2(String xmlName, String xslName, String goldName)426 public void testlet2(String xmlName, String xslName, String goldName) 427 { 428 try 429 { 430 reporter.logStatusMsg("testlet2: verify setOutputProperty(s, s)"); 431 432 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 433 dbf.setNamespaceAware(true); // sc for Xerces 434 DocumentBuilder db = dbf.newDocumentBuilder(); 435 reporter.logTraceMsg("docBld.parse(" + xslName + ")"); 436 Document document = db.parse(new File(xslName)); 437 DOMSource domSource = new DOMSource(document); 438 domSource.setSystemId(QetestUtils.filenameToURL(xslName)); // sc 439 440 TransformerFactory tfactory = TransformerFactory.newInstance(); 441 Transformer transformer = tfactory.newTransformer(domSource); 442 Properties xslProps = transformer.getOutputProperties(); 443 reporter.logHashtable(Logger.STATUSMSG, xslProps, 444 "Properties originally from the stylesheet"); 445 446 reporter.logTraceMsg("new StreamSource(new FileInputStream(" + xmlName + "))"); 447 StreamSource streamSource = new StreamSource(new FileInputStream(xmlName)); 448 FileOutputStream fos = new FileOutputStream(outNames.nextName()); 449 StreamResult streamResult = new StreamResult(fos); 450 451 // Verify setting a whole block of properties 452 reporter.logTraceMsg("transformer.setOutputProperty(indent, no)"); 453 transformer.setOutputProperty("indent", "no"); 454 455 reporter.logTraceMsg("transformer.transform(xml, " + outNames.currentName() + ")"); 456 transformer.transform(streamSource, streamResult); 457 fos.close(); 458 459 if (Logger.PASS_RESULT 460 != fileChecker.check(reporter, 461 new File(outNames.currentName()), 462 new File(goldName), 463 "(t2)transform after setOutputProperty(indent, no) into: " + outNames.currentName()) 464 ) 465 { 466 reporter.logInfoMsg("(t2)transform after setOutputProperty(indent, no) failure reason:" + fileChecker.getExtendedInfo()); 467 } 468 } 469 catch (Throwable t) 470 { 471 reporter.checkFail("testlet threw: " + t.toString()); 472 reporter.logThrowable(Logger.WARNINGMSG, t, "testlet threw "); 473 } 474 } 475 /** 476 * testlet1: verify setOutputProperty(s, s). 477 * @author Krishna.Meduri@eng.sun.com 478 */ testlet3(String xmlName, String xslName, String goldName)479 public void testlet3(String xmlName, String xslName, String goldName) 480 { 481 try 482 { 483 reporter.logInfoMsg("testlet3: verify setOutputProperty(s, s)"); 484 485 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 486 dbf.setNamespaceAware(true); // sc for Xerces 487 DocumentBuilder db = dbf.newDocumentBuilder(); 488 reporter.logTraceMsg("docBld.parse(" + xslName + ")"); 489 Document document = db.parse(new File(xslName)); 490 DOMSource domSource = new DOMSource(document); 491 domSource.setSystemId(QetestUtils.filenameToURL(xslName)); // sc 492 493 TransformerFactory tfactory = TransformerFactory.newInstance(); 494 Transformer transformer = tfactory.newTransformer(domSource); 495 Properties xslProps = transformer.getOutputProperties(); 496 reporter.logHashtable(Logger.STATUSMSG, xslProps, 497 "Properties originally from the stylesheet"); 498 499 reporter.logTraceMsg("new StreamSource(new FileInputStream(" + xmlName + "))"); 500 StreamSource streamSource = new StreamSource(new FileInputStream(xmlName)); 501 FileOutputStream fos = new FileOutputStream(outNames.nextName()); 502 StreamResult streamResult = new StreamResult(fos); 503 504 // Verify setting single property 505 reporter.logTraceMsg("transformer.setOutputProperty(method, text)"); 506 transformer.setOutputProperty("method", "text"); 507 508 reporter.logTraceMsg("transformer.transform(xml, " + outNames.currentName() + ")"); 509 transformer.transform(streamSource, streamResult); 510 fos.close(); 511 512 if (Logger.PASS_RESULT 513 != fileChecker.check(reporter, 514 new File(outNames.currentName()), 515 new File(goldName), 516 "(t3)transform after setOutputProperty(method, text) into: " + outNames.currentName()) 517 ) 518 { 519 reporter.logInfoMsg("(t3)transform after setOutputProperty(method, text) failure reason:" + fileChecker.getExtendedInfo()); 520 } 521 } 522 catch (Throwable t) 523 { 524 reporter.checkFail("testlet threw: " + t.toString()); 525 reporter.logThrowable(Logger.WARNINGMSG, t, "testlet threw "); 526 } 527 } 528 529 /** 530 * Convenience method to print out usage information - update if needed. 531 * @return String denoting usage of this test class 532 */ usage()533 public String usage() 534 { 535 return ("Common [optional] options supported by OutputPropertiesTest:\n" 536 + "(Note: assumes inputDir=tests\\api)\n" 537 + super.usage()); // Grab our parent classes usage as well 538 } 539 540 541 /** 542 * Main method to run test from the command line - can be left alone. 543 * @param args command line argument array 544 */ main(String[] args)545 public static void main(String[] args) 546 { 547 548 OutputPropertiesTest app = new OutputPropertiesTest(); 549 550 app.doMain(args); 551 } 552 } 553