1 26 27 package net.sourceforge.groboutils.codecoverage.v2.ant; 28 29 import java.io.File ; 30 import java.io.IOException ; 31 import java.util.Enumeration ; 32 import java.util.Vector ; 33 34 import net.sourceforge.groboutils.codecoverage.v2.IAnalysisModule; 35 import net.sourceforge.groboutils.codecoverage.v2.IChannelLogReader; 36 import net.sourceforge.groboutils.codecoverage.v2.datastore.AnalysisModuleSet; 37 import net.sourceforge.groboutils.codecoverage.v2.datastore.DirMetaDataReader; 38 import net.sourceforge.groboutils.codecoverage.v2.datastore.IMetaDataReader; 39 import net.sourceforge.groboutils.codecoverage.v2.logger.DirectoryChannelLogReader; 40 import net.sourceforge.groboutils.codecoverage.v2.report.AnalysisModuleData; 41 import net.sourceforge.groboutils.codecoverage.v2.report.IReportGenerator; 42 import net.sourceforge.groboutils.codecoverage.v2.report.XmlCombinedReportGenerator; 43 import net.sourceforge.groboutils.codecoverage.v2.report.XmlReportGenerator; 44 import net.sourceforge.groboutils.codecoverage.v2.util.ILogFilter; 45 import net.sourceforge.groboutils.codecoverage.v2.util.SingleLogFilter; 46 47 import org.apache.tools.ant.BuildException; 48 import org.apache.tools.ant.Project; 49 import org.apache.tools.ant.Task; 50 import org.apache.tools.ant.types.EnumeratedAttribute; 51 52 import org.w3c.dom.Document ; 53 import org.w3c.dom.Element ; 54 55 56 57 58 68 public class GroboReportTask extends Task 69 { 70 private File baselogdir; 71 private File logdir; 72 private File datadir; 73 private Vector singleStyles = new Vector (); 74 private Vector comboStyles = new Vector (); 75 private boolean failOnError = true; 76 private LogFilter filter = null; 77 78 79 public static final class FilterTypeAttribute extends EnumeratedAttribute 80 { 81 private String [] types = { "single", "none" }; 82 public String [] getValues() 83 { 84 return this.types; 85 } 86 } 87 88 public static class LogFilter 89 { 90 private String type = "none"; 91 92 public void setType( FilterTypeAttribute fta ) 93 { 94 this.type = fta.getValue(); 95 } 96 97 public ILogFilter getFilter() 98 { 99 if ("single".equalsIgnoreCase( this.type )) 100 { 101 return new SingleLogFilter(); 102 } 103 return null; 105 } 106 } 107 108 109 112 public void setLogDir( File dir ) 113 { 114 this.baselogdir = dir; 115 } 116 117 118 123 public void addLogFilter( LogFilter lf ) 124 { 125 this.filter = lf; 126 } 127 128 129 132 public void addXml( XmlReportStyle xrs ) 133 { 134 _addSingle( xrs ); 136 _addCombo( xrs ); 137 } 138 139 140 143 public void addXsl( SimpleXslReportStyle sxrs ) 144 { 145 _addSingle( sxrs ); 146 } 147 148 149 152 public void addSourceXsl( SourceXslReportStyle sxrs ) 153 { 154 _addCombo( sxrs ); 155 } 156 157 158 161 public void addSimpleHtml( SimpleHtmlReportStyle shrs ) 162 { 163 _addSingle( shrs ); 164 } 165 166 167 170 public void addSimple( SimpleHtmlReportStyle shrs ) 171 { 172 _addSingle( shrs ); 173 } 174 175 176 179 public void addSourceHtml( SourceHtmlReportStyle shrs ) 180 { 181 _addCombo( shrs ); 182 } 183 184 185 188 public void addSource( SourceHtmlReportStyle shrs ) 189 { 190 _addCombo( shrs ); 191 } 192 193 194 197 public void addFailOn( FailOnReportStyle fors ) 198 { 199 _addCombo( fors ); 200 } 201 202 203 public void setFailOnError( boolean f ) 204 { 205 this.failOnError = f; 206 } 207 208 209 210 public void execute() 211 throws BuildException 212 { 213 try 214 { 215 setupDirectories(); 216 } 217 catch (IOException ioe) 218 { 219 throw new BuildException( "Error setting up the directories.", ioe ); 220 } 221 222 223 IMetaDataReader mdr = createMetaDataReader(); 224 IReportGenerator rg = new XmlReportGenerator(); 225 boolean errors = false; 226 Vector reports = new Vector (); 227 Vector errorList = new Vector (); 228 try 229 { 230 AnalysisModuleSet ams = mdr.getAnalysisModuleSet(); 231 IAnalysisModule amL[] = ams.getAnalysisModules(); 232 for (int i = 0; i < amL.length; ++i) 233 { 234 try 235 { 236 IChannelLogReader clr = 237 createChannelLogReader( amL[i], ams ); 238 AnalysisModuleData amd = 239 new AnalysisModuleData( amL[i], mdr, clr ); 240 Element rootEl = createReport( amL[i], amd, rg ); 241 if (rootEl == null) 242 { 243 log( "Creating the report returned null", Project.MSG_WARN ); 244 errors = true; 245 } 246 else 247 { 248 Document doc = rootEl.getOwnerDocument(); 249 reports.addElement( doc ); 250 processSingleStyles( doc, amL[i].getMeasureName() ); 251 } 252 } 253 catch (IllegalArgumentException iae) 254 { 255 iae.printStackTrace(); 256 log( iae.getMessage(), Project.MSG_WARN ); 257 errors = true; 258 } 259 } 260 finishSingleStyles( errorList ); 261 } 262 catch (IOException e) 263 { 264 throw new BuildException( 265 "I/O Exception while creating a report.", e, getLocation() ); 266 } 267 finally 268 { 269 try 270 { 271 mdr.close(); 272 } 273 catch (IOException e) 274 { 275 throw new BuildException( 276 "I/O Exception while closing meta-data reader.", e, 277 getLocation() ); 278 } 279 } 280 rg = null; 281 mdr = null; 282 try 283 { 284 processCombos( reports, errorList ); 285 } 286 catch (IOException e) 287 { 288 throw new BuildException( 289 "I/O Exception while creating a report.", e, getLocation() ); 290 } 291 292 293 if (errors && this.failOnError) 294 { 295 throw new BuildException( 296 "No coverage logs were generated, or the logs "+ 297 "are not located under '"+this.logdir+"'.", 298 getLocation() ); 299 } 300 301 if (errorList.size() > 0) 302 { 303 StringBuffer sb = new StringBuffer (); 304 Enumeration e = errorList.elements(); 305 while (e.hasMoreElements()) 306 { 307 sb.append( "; " ).append( (String )e.nextElement() ); 308 } 309 if (this.failOnError) 310 { 311 throw new BuildException( 312 "Error conditions caused failure" + sb.toString() ); 313 } 314 else 315 { 316 log( "Warning: " + sb.toString(), Project.MSG_WARN ); 317 } 318 } 319 } 320 321 322 323 324 private void processCombos( Vector reports, Vector errorList ) 325 throws BuildException, IOException 326 { 327 if (this.comboStyles.size() > 0) 330 { 331 Document docs[] = new Document [ reports.size() ]; 333 reports.copyInto( docs ); 334 335 reports.removeAllElements(); 338 339 XmlCombinedReportGenerator gen = new XmlCombinedReportGenerator(); 340 log( "Creating combined coverage report", Project.MSG_INFO ); 341 Element ret = null; 342 try 343 { 344 ret = gen.createReport( docs ); 345 } 346 catch (IllegalArgumentException iae) 347 { 348 350 iae.printStackTrace(); 353 log( iae.getMessage(), Project.MSG_WARN ); 354 ret = null; 355 } 356 docs = null; 357 358 if (ret != null) 359 { 360 processComboStyles( ret.getOwnerDocument() ); 361 finishComboStyles( errorList ); 362 } 363 } 364 } 365 366 367 368 private void processSingleStyles( Document doc, String moduleName ) 369 throws BuildException, IOException 370 { 371 processStyles( doc, moduleName, this.singleStyles.elements() ); 372 } 373 374 375 private void finishSingleStyles( Vector errorList ) 376 throws BuildException, IOException 377 { 378 finishStyles( this.singleStyles.elements(), errorList ); 379 } 380 381 382 private void processComboStyles( Document doc ) 383 throws BuildException, IOException 384 { 385 processStyles( doc, "all", this.comboStyles.elements() ); 386 } 387 388 389 private void finishComboStyles( Vector errorList ) 390 throws BuildException, IOException 391 { 392 finishStyles( this.comboStyles.elements(), errorList ); 393 } 394 395 396 private void processStyles( Document doc, String moduleName, 397 Enumeration styles ) 398 throws BuildException, IOException 399 { 400 while (styles.hasMoreElements()) 401 { 402 IReportStyle rs = (IReportStyle)styles.nextElement(); 403 rs.generateReport( getProject(), doc, moduleName ); 404 } 405 } 406 407 408 private void finishStyles( Enumeration styles, Vector errors ) 409 throws BuildException, IOException 410 { 411 while (styles.hasMoreElements()) 412 { 413 IReportStyle rs = (IReportStyle)styles.nextElement(); 414 rs.reportComplete( getProject(), errors ); 415 } 416 } 417 418 419 420 424 public void _addSingle( IReportStyle rs ) 425 { 426 if (rs != null) 427 { 428 this.singleStyles.addElement( rs ); 429 } 430 } 431 432 433 437 public void _addCombo( IReportStyle rs ) 438 { 439 if (rs != null) 440 { 441 this.comboStyles.addElement( rs ); 442 } 443 } 444 445 446 private Element createReport( IAnalysisModule am, 447 AnalysisModuleData amd, IReportGenerator rg ) 448 throws IOException , BuildException 449 { 450 log( "Creating coverage report for module "+am.getMeasureName(), 451 Project.MSG_INFO ); 452 Element ret = null; 453 try 454 { 455 ret = rg.createReport( am, amd ); 456 } 457 catch (IllegalArgumentException iae) 458 { 459 461 iae.printStackTrace(); 464 log( iae.getMessage(), Project.MSG_WARN ); 465 ret = null; 466 } 467 468 return ret; 469 } 470 471 472 private IChannelLogReader createChannelLogReader( IAnalysisModule am, 473 AnalysisModuleSet ams ) 474 throws IOException 475 { 476 short mi = ams.getAnalysisModuleIndex( am ); 477 IChannelLogReader clr = new DirectoryChannelLogReader( this.logdir, 478 mi ); 479 return clr; 480 } 481 482 483 private IMetaDataReader createMetaDataReader() 484 throws BuildException 485 { 486 try 487 { 488 return new DirMetaDataReader( this.datadir ); 489 } 490 catch (IOException e) 491 { 492 throw new BuildException( "I/O error creating meta-data reader.", 493 e, getLocation() ); 494 } 495 } 496 497 498 499 504 private void setupDirectories() 505 throws IOException , BuildException 506 { 507 if (this.baselogdir == null) 509 { 510 throw new BuildException( "Did not specify attribute 'datadir'." ); 511 } 512 if (this.datadir == null) 513 { 514 this.datadir = new File ( this.baselogdir, "data" ); 515 } 516 if (this.logdir == null) 517 { 518 this.logdir = new File ( this.baselogdir, "logs" ); 519 } 520 521 522 if (!this.datadir.exists() || 523 !this.datadir.isDirectory()) 524 { 525 throw new BuildException("Data directory setting ("+ 526 this.datadir+") does not exist or is not a directory."); 527 } 528 if (!this.logdir.exists()) 529 { 530 this.logdir.mkdirs(); 531 } 532 if (!this.logdir.isDirectory()) 533 { 534 throw new BuildException("Log directory setting ("+ 535 this.logdir+") is not a directory."); 536 } 537 String modules[] = this.datadir.list(); 538 if (modules == null || modules.length <= 0) 539 { 540 throw new BuildException("There are no module data directories in "+ 541 this.datadir+"."); 542 } 543 544 String indicies[] = this.logdir.list(); 545 if (indicies == null) 546 { 547 indicies = new String [0]; 548 } 549 int count = modules.length; 550 551 for (int i = 0; i <= count; ++i) 552 { 553 String dirname = Integer.toString(i); 554 boolean found = false; 555 for (int j = 0; j < indicies.length; ++j) 556 { 557 if (indicies[j].equals( dirname )) 558 { 559 found = true; 560 break; 561 } 562 } 563 if (!found) 564 { 565 File f = new File ( this.logdir, dirname ); 566 f.mkdirs(); 567 } 568 } 569 570 if (this.filter != null) 571 { 572 ILogFilter lf = this.filter.getFilter(); 573 if (lf != null) 574 { 575 lf.process( count, this.logdir ); 576 } 577 } 578 } 579 } 580 581 | Popular Tags |