1 18 package org.apache.batik.test.xml; 19 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.io.FileOutputStream ; 23 import java.io.InputStream ; 24 import java.io.OutputStream ; 25 import java.io.BufferedInputStream ; 26 import java.io.BufferedOutputStream ; 27 import java.io.FileWriter ; 28 import java.io.IOException ; 29 import java.io.PrintWriter ; 30 import java.io.StringWriter ; 31 import java.io.Writer ; 32 33 import java.net.URL ; 34 35 import java.util.Calendar ; 36 37 import javax.xml.parsers.DocumentBuilderFactory ; 38 import javax.xml.parsers.DocumentBuilder ; 39 40 import org.apache.batik.test.TestReport; 41 import org.apache.batik.test.TestReportProcessor; 42 import org.apache.batik.test.TestSuite; 43 import org.apache.batik.test.TestException; 44 45 import org.apache.batik.util.XMLConstants; 46 47 import org.w3c.dom.Attr ; 48 import org.w3c.dom.Document ; 49 import org.w3c.dom.Element ; 50 import org.w3c.dom.NamedNodeMap ; 51 import org.w3c.dom.Node ; 52 import org.w3c.dom.NodeList ; 53 import org.w3c.dom.DOMImplementation ; 54 55 67 public class XMLTestReportProcessor 68 implements TestReportProcessor, 69 XTRConstants, XMLConstants { 70 74 public static interface XMLReportConsumer { 75 81 public void onNewReport(File xmlReport, 82 File reportDirectory) throws Exception ; 83 } 84 85 88 public static final String ERROR_REPORT_DIRECTORY_UNUSABLE 89 = "xml.XMLTestReportProcessor.error.report.directory.unusable"; 90 91 94 public static final String ERROR_REPORT_RESOURCES_DIRECTORY_UNUSABLE 95 = "xml.XMLTestReportProcessor.error.report.resources.directory.unusable"; 96 97 100 public static final String XML_TEST_REPORT_DEFAULT_DIRECTORY 101 = Messages.formatMessage("XMLTestReportProcessor.config.xml.test.report.default.directory", null); 102 103 106 public static final String XML_REPORT_DIRECTORY 107 = Messages.formatMessage("XMLTestReportProcessor.xml.report.directory", null); 108 109 113 public static final String XML_RESOURCES_DIRECTORY 114 = Messages.formatMessage("XMLTestReportProcessor.xml.resources.directory", null); 115 116 119 public static final String XML_TEST_REPORT_NAME 120 = Messages.formatMessage("XMLTestReportProcessor.config.xml.test.report.name", null); 121 122 126 protected XMLReportConsumer consumer; 127 128 131 protected String reportDate; 132 133 136 protected File reportDirectory; 137 138 141 protected File xmlDirectory; 142 143 146 protected File xmlResourcesDirectory; 147 148 151 public XMLTestReportProcessor(){ 152 } 153 154 158 public XMLTestReportProcessor(XMLTestReportProcessor.XMLReportConsumer consumer){ 159 this.consumer = consumer; 160 } 161 162 166 public void processReport(TestReport report) 167 throws TestException { 168 169 173 initializeReportDirectories(); 174 175 try { 176 177 182 DocumentBuilder docBuilder 183 = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 184 DOMImplementation impl 185 = docBuilder.getDOMImplementation(); 186 187 Document document = null; 188 189 if(report.getTest() instanceof TestSuite){ 190 document = impl.createDocument(XTR_NAMESPACE_URI, 191 XTR_TEST_SUITE_REPORT_TAG, null); 192 } 193 else { 194 document = impl.createDocument(XTR_NAMESPACE_URI, 195 XTR_TEST_REPORT_TAG, null); 196 } 197 198 Element root = document.getDocumentElement(); 199 200 root.setAttribute(XTR_DATE_ATTRIBUTE, 201 reportDate); 202 203 processReport(report, root, document); 204 205 File xmlReport = serializeReport(root); 206 207 if(consumer != null){ 208 consumer.onNewReport(xmlReport, getReportDirectory()); 209 } 210 211 } catch(Exception e) { 212 StringWriter sw = new StringWriter (); 213 PrintWriter pw = new PrintWriter (sw); 214 e.printStackTrace(pw); 215 throw new TestException(INTERNAL_ERROR, 216 new Object [] { e.getClass().getName(), 217 e.getMessage(), 218 sw.toString() }, 219 e); 220 } 221 } 222 223 228 public void checkDirectory(File dir, 229 String errorCode) 230 throws TestException { 231 boolean dirOK = false; 232 try{ 233 if(!dir.exists()){ 234 dirOK = dir.mkdir(); 235 } 236 else if(dir.isDirectory()){ 237 dirOK = true; 238 } 239 }finally{ 240 if(!dirOK){ 241 throw new TestException(errorCode, 242 new Object [] {dir.getAbsolutePath()}, 243 null); 244 245 } 246 } 247 } 248 249 256 public void initializeReportDirectories() throws TestException { 257 File baseReportDir = new File (XML_TEST_REPORT_DEFAULT_DIRECTORY); 261 checkDirectory(baseReportDir, ERROR_REPORT_DIRECTORY_UNUSABLE); 262 263 Calendar c = Calendar.getInstance(); 267 String dirName = "" + c.get(Calendar.YEAR) + "." 268 + makeTwoDigits (c.get(Calendar.MONTH)+1) + "." 269 + makeTwoDigits (c.get(Calendar.DAY_OF_MONTH)) + "-" 270 + makeTwoDigits (c.get(Calendar.HOUR_OF_DAY)) + "h" 271 + makeTwoDigits (c.get(Calendar.MINUTE)) + "m" 272 + makeTwoDigits (c.get(Calendar.SECOND)) + "s"; 273 274 reportDate = dirName; 275 reportDirectory = new File (baseReportDir, dirName); 276 checkDirectory(reportDirectory, ERROR_REPORT_DIRECTORY_UNUSABLE); 277 278 xmlDirectory = new File (reportDirectory, XML_REPORT_DIRECTORY); 283 checkDirectory(xmlDirectory, ERROR_REPORT_DIRECTORY_UNUSABLE); 284 285 xmlResourcesDirectory = new File (xmlDirectory, XML_RESOURCES_DIRECTORY); 286 checkDirectory(xmlResourcesDirectory, ERROR_REPORT_DIRECTORY_UNUSABLE); 287 } 288 289 292 protected String makeTwoDigits(int i){ 293 if(i > 9){ 294 return "" + i; 295 } 296 else{ 297 return "0" + i; 298 } 299 } 300 301 304 public File getReportDirectory(){ 305 return reportDirectory; 306 } 307 308 312 public File getReportResourcesDirectory() { 313 return xmlResourcesDirectory; 314 } 315 316 320 protected void processReport(TestReport report, 321 Element reportElement, 322 Document reportDocument) throws IOException { 323 if(report == null){ 324 throw new IllegalArgumentException (); 325 } 326 327 reportElement.setAttribute(XTR_TEST_NAME_ATTRIBUTE, 328 report.getTest().getName()); 329 330 String id = report.getTest().getQualifiedId(); 331 if( !"".equals(id) ){ 332 reportElement.setAttribute(XTR_ID_ATTRIBUTE, 333 id 334 ); 335 } 336 337 String status = report.hasPassed() 338 ? XTR_PASSED_VALUE 339 : XTR_FAILED_VALUE; 340 341 reportElement.setAttribute(XTR_STATUS_ATTRIBUTE, 342 status); 343 344 String className = report.getTest().getClass().getName(); 345 346 reportElement.setAttribute(XTR_CLASS_ATTRIBUTE, 347 className); 348 349 if(!report.hasPassed()){ 350 reportElement.setAttribute(XTR_ERROR_CODE_ATTRIBUTE, 351 report.getErrorCode()); 352 } 353 354 TestReport.Entry[] entries = report.getDescription(); 355 int n = entries != null ? entries.length : 0; 356 357 if (n>0) { 358 Element descriptionElement 359 = reportDocument.createElementNS(null, 360 XTR_DESCRIPTION_TAG); 361 362 reportElement.appendChild(descriptionElement); 363 364 for(int i=0; i<n; i++){ 365 processEntry(entries[i], 366 descriptionElement, 367 reportDocument); 368 369 } 370 } 371 } 372 373 protected void processEntry(TestReport.Entry entry, 374 Element descriptionElement, 375 Document reportDocument) throws IOException { 376 377 Object value = entry.getValue(); 378 String key = entry.getKey(); 379 380 if(value instanceof TestReport){ 381 TestReport report = (TestReport)value; 382 383 Element reportElement = null; 384 385 if(report.getTest() instanceof TestSuite){ 386 reportElement 387 = reportDocument.createElementNS(XTR_NAMESPACE_URI, 388 XTR_TEST_SUITE_REPORT_TAG); 389 } 390 else{ 391 reportElement 392 = reportDocument.createElementNS(XTR_NAMESPACE_URI, 393 XTR_TEST_REPORT_TAG); 394 } 395 396 descriptionElement.appendChild(reportElement); 397 processReport((TestReport)entry.getValue(), 398 reportElement, 399 reportDocument); 400 } 401 else if(value instanceof URL ){ 402 Element entryElement 403 = reportDocument.createElementNS(XTR_NAMESPACE_URI, 404 XTR_URI_ENTRY_TAG); 405 406 descriptionElement.appendChild(entryElement); 407 408 entryElement.setAttribute(XTR_KEY_ATTRIBUTE, 409 key.toString()); 410 411 entryElement.setAttribute(XTR_VALUE_ATTRIBUTE, 412 value.toString()); 413 414 } 415 else if(value instanceof File ){ 416 File tmpFile = (File )value; 422 423 File tmpFileCopy = createResourceFileForName(tmpFile.getName()); 424 425 copy(tmpFile, tmpFileCopy); 426 427 Element entryElement 428 = reportDocument.createElementNS(XTR_NAMESPACE_URI, 429 XTR_FILE_ENTRY_TAG); 430 431 descriptionElement.appendChild(entryElement); 432 433 entryElement.setAttribute(XTR_KEY_ATTRIBUTE, 434 key.toString()); 435 436 entryElement.setAttribute(XTR_VALUE_ATTRIBUTE, 437 tmpFileCopy.toURL().toString()); 438 439 } 440 else { 441 442 Element entryElement 443 = reportDocument.createElementNS(XTR_NAMESPACE_URI, 444 XTR_GENERIC_ENTRY_TAG); 445 446 descriptionElement.appendChild(entryElement); 447 448 entryElement.setAttribute(XTR_KEY_ATTRIBUTE, 449 key.toString()); 450 451 Attr a = reportDocument.createAttribute(XTR_VALUE_ATTRIBUTE); 452 a.setValue(value!=null?value.toString():"null"); 453 entryElement.setAttributeNode(a); 454 } 455 } 456 457 465 protected File createResourceFileForName(String fileName){ 466 File r = new File (xmlResourcesDirectory, fileName); 467 if(!r.exists()){ 468 return r; 469 } 470 else{ 471 return createResourceFileForName(fileName, 1); 472 } 473 } 474 475 protected File createResourceFileForName(String fileName, 476 int instance){ 477 int n = fileName.lastIndexOf('.'); 479 String iFileName = fileName + instance; 480 if(n != -1){ 481 iFileName = fileName.substring(0, n) + instance 482 + fileName.substring(n, fileName.length()); 483 } 484 485 File r = new File (xmlResourcesDirectory, iFileName); 486 if(!r.exists()){ 487 return r; 488 } 489 else{ 490 return createResourceFileForName(fileName, 491 instance + 1); 492 } 493 } 494 495 498 protected void copy(File in, File out) throws IOException { 499 InputStream is = new BufferedInputStream (new FileInputStream (in)); 500 OutputStream os = new BufferedOutputStream (new FileOutputStream (out)); 501 502 final byte[] b = new byte[1024]; 503 int n = -1; 504 while( (n = is.read(b)) != -1 ){ 505 os.write(b, 0, n); 506 } 507 508 is.close(); 509 os.close(); 510 } 511 512 515 protected File serializeReport(Element reportElement) throws IOException { 516 File reportFile = new File (xmlDirectory, 520 XML_TEST_REPORT_NAME); 521 522 FileWriter fw = new FileWriter (reportFile); 523 524 serializeElement(reportElement, 525 "", 526 fw); 527 528 fw.close(); 529 530 return reportFile; 531 } 532 533 534 static private String EOL; 535 536 static private String PROPERTY_LINE_SEPARATOR = "line.separator"; 537 static private String PROPERTY_LINE_SEPARATOR_DEFAULT = "\n"; 538 static { 539 String temp; 540 try { 541 temp = System.getProperty (PROPERTY_LINE_SEPARATOR, 542 PROPERTY_LINE_SEPARATOR_DEFAULT); 543 } catch (SecurityException e) { 544 temp = PROPERTY_LINE_SEPARATOR_DEFAULT; 545 } 546 EOL = temp; 547 } 548 549 protected void serializeElement(Element element, 550 String prefix, 551 Writer writer) throws IOException { 552 writer.write(prefix); 553 writer.write(XML_OPEN_TAG_START); 554 writer.write(element.getTagName()); 555 556 serializeAttributes(element, 557 writer); 558 559 NodeList children = element.getChildNodes(); 560 if(children != null && children.getLength() > 0){ 561 writer.write(XML_OPEN_TAG_END_CHILDREN); 562 writer.write(EOL); 563 int n = children.getLength(); 564 for(int i=0; i<n; i++){ 565 Node child = children.item(i); 566 if(child.getNodeType() == Node.ELEMENT_NODE){ 567 serializeElement((Element )child, 568 prefix + XML_TAB, 569 writer); 570 } 571 } 572 writer.write(prefix); 573 writer.write(XML_CLOSE_TAG_START); 574 writer.write(element.getTagName()); 575 writer.write(XML_CLOSE_TAG_END); 576 } 577 else{ 578 writer.write(XML_OPEN_TAG_END_NO_CHILDREN); 579 } 580 581 writer.write(EOL); 582 583 } 584 585 protected void serializeAttributes(Element element, 586 Writer writer) throws IOException { 587 NamedNodeMap attributes = element.getAttributes(); 588 if (attributes != null){ 589 int nAttr = attributes.getLength(); 590 for(int i=0; i<nAttr; i++){ 591 Attr attr = (Attr )attributes.item(i); 592 writer.write(XML_SPACE); 593 writer.write(attr.getName()); 594 writer.write(XML_EQUAL_SIGN); 595 writer.write(XML_DOUBLE_QUOTE); 596 writer.write(encode(attr.getValue())); 597 writer.write(XML_DOUBLE_QUOTE); 598 } 599 } 600 } 601 602 606 protected String encode(String attrValue){ 607 StringBuffer sb = new StringBuffer (attrValue); 608 replace(sb, XML_CHAR_AMP, XML_ENTITY_AMP); 609 replace(sb, XML_CHAR_LT, XML_ENTITY_LT); 610 replace(sb, XML_CHAR_GT, XML_ENTITY_GT); 611 replace(sb, XML_CHAR_QUOT, XML_ENTITY_QUOT); 612 replace(sb, XML_CHAR_APOS, XML_ENTITY_APOS); 613 return sb.toString(); 614 } 615 616 protected void replace(StringBuffer s, 617 char c, 618 String r){ 619 String v = s.toString() + 1; 620 int i = v.length(); 621 622 while( (i=v.lastIndexOf(c, --i)) != -1 ){ 623 s.deleteCharAt(i); 624 s.insert(i, r); 625 } 626 } 627 } 628 | Popular Tags |