1 26 27 package net.sourceforge.groboutils.codecoverage.v2.ant; 28 29 import java.io.File ; 30 import java.io.FileOutputStream ; 31 import java.io.IOException ; 32 import java.io.OutputStreamWriter ; 33 import java.util.Enumeration ; 34 import java.util.Vector ; 35 36 import net.sourceforge.groboutils.codecoverage.v2.IAnalysisModule; 37 import net.sourceforge.groboutils.codecoverage.v2.IChannelLogReader; 38 import net.sourceforge.groboutils.codecoverage.v2.datastore.AnalysisModuleSet; 39 import net.sourceforge.groboutils.codecoverage.v2.datastore.DirMetaDataReader; 40 import net.sourceforge.groboutils.codecoverage.v2.datastore.IMetaDataReader; 41 import net.sourceforge.groboutils.codecoverage.v2.logger.DirectoryChannelLogReader; 42 import net.sourceforge.groboutils.codecoverage.v2.report.AnalysisModuleData; 43 import net.sourceforge.groboutils.codecoverage.v2.report.IReportGenerator; 44 import net.sourceforge.groboutils.codecoverage.v2.report.OutputXml; 45 import net.sourceforge.groboutils.codecoverage.v2.report.XmlCombinedReportGenerator; 46 import net.sourceforge.groboutils.codecoverage.v2.report.XmlReportGenerator; 47 48 import org.apache.tools.ant.BuildException; 49 import org.apache.tools.ant.Project; 50 import org.apache.tools.ant.Task; 51 import org.w3c.dom.Document ; 52 import org.w3c.dom.Element ; 53 54 55 63 public class CoverageReportTask extends Task 64 { 65 private File datadir = null; 66 private File logdir = null; 67 private File outdir = null; 68 private String prefix = "CoverageReport-"; 69 private String postfix = ".xml"; 70 private boolean failonerror = false; 71 private Vector singleReports = new Vector (); 72 private Vector comboReports = new Vector (); 73 74 75 public void setDataDir( File f ) 76 { 77 this.datadir = f; 78 } 79 80 81 public void setLogDir( File f ) 82 { 83 this.logdir = f; 84 } 85 86 87 public void setOutDir( File f ) 88 { 89 this.outdir = f; 90 } 91 92 93 public void setReportFilePrefix( String s ) 94 { 95 this.prefix = s; 96 } 97 98 99 public void setReportFileExtension( String s ) 100 { 101 this.postfix = s; 102 } 103 104 105 public void setFailOnError( boolean val ) 106 { 107 this.failonerror = val; 108 } 109 110 111 public SimpleHtmlReportStyle createSimpleStyle() 112 { 113 SimpleHtmlReportStyle style = new SimpleHtmlReportStyle(); 114 this.singleReports.addElement( style ); 115 return style; 116 } 117 118 119 public SourceHtmlReportStyle createSourceStyle() 120 { 121 SourceHtmlReportStyle style = new SourceHtmlReportStyle(); 122 this.comboReports.addElement( style ); 123 return style; 124 } 125 126 127 128 public void execute() 129 throws BuildException 130 { 131 log( "Use of the CoverageReport task is deprecated; please "+ 132 "use the 'grobo-report' task instead. You may need to "+ 133 "change the taskdef to reference the new resource file, located "+ 134 "at [ant-grobocoverage.properties], instead of "+ 135 "[net/sourceforge/groboutils/codecoverage/grobocoverage.properties"+ 136 "].", Project.MSG_WARN ); 137 138 if (this.datadir == null) 140 { 141 throw new BuildException( "Did not specify attribute 'datadir'." ); 142 } 143 if (this.logdir == null) 144 { 145 throw new BuildException( "Did not specify attribute 'logdir'." ); 146 } 147 if (this.outdir == null) 148 { 149 throw new BuildException( "Did not specify attribute 'outdir'." ); 150 } 151 if (this.prefix == null || this.postfix == null) 152 { 153 throw new BuildException( "Output report name format is null." ); 154 } 155 156 157 try 158 { 159 setupDirectories(); 160 } 161 catch (IOException ioe) 162 { 163 throw new BuildException( "Error setting up the directories.", ioe ); 164 } 165 166 167 IMetaDataReader mdr = createMetaDataReader(); 168 IReportGenerator rg = new XmlReportGenerator(); 169 boolean errors = false; 170 try 171 { 172 Vector reports = new Vector (); 173 AnalysisModuleSet ams = mdr.getAnalysisModuleSet(); 174 IAnalysisModule amL[] = ams.getAnalysisModules(); 175 for (int i = 0; i < amL.length; ++i) 176 { 177 try 178 { 179 IChannelLogReader clr = 180 createChannelLogReader( amL[i], ams ); 181 AnalysisModuleData amd = 182 new AnalysisModuleData( amL[i], mdr, clr ); 183 Element rootEl = createReport( amL[i], amd, rg ); 184 if (rootEl == null) 185 { 186 errors = true; 187 } 188 else 189 { 190 Document doc = rootEl.getOwnerDocument(); 191 reports.addElement( doc ); 192 processStyles( doc, amL[i].getMeasureName() ); 193 } 194 } 195 catch (IllegalArgumentException iae) 196 { 197 iae.printStackTrace(); 198 log( iae.getMessage(), Project.MSG_WARN ); 199 errors = true; 200 } 201 } 202 finishStyles( reports ); 203 } 204 catch (IOException e) 205 { 206 throw new BuildException( 207 "I/O Exception while creating a report.", e, getLocation() ); 208 } 209 finally 210 { 211 try 212 { 213 mdr.close(); 214 } 215 catch (IOException e) 216 { 217 throw new BuildException( 218 "I/O Exception while closing meta-data reader.", e, 219 getLocation() ); 220 } 221 } 222 223 224 if (errors && this.failonerror) 225 { 226 throw new BuildException( 227 "No coverage logs were generated, or the logs "+ 228 "are not located under '"+this.logdir+"'.", 229 getLocation() ); 230 } 231 } 232 233 234 239 private void setupDirectories() 240 throws IOException , BuildException 241 { 242 if (!this.datadir.exists() || 243 !this.datadir.isDirectory()) 244 { 245 throw new BuildException("Data directory setting ("+ 246 this.datadir+") does not exist or is not a directory."); 247 } 248 if (!this.logdir.exists()) 249 { 250 this.logdir.mkdirs(); 251 } 252 if (!this.logdir.isDirectory()) 253 { 254 throw new BuildException("Log directory setting ("+ 255 this.logdir+") is not a directory."); 256 } 257 String modules[] = this.datadir.list(); 258 if (modules == null || modules.length <= 0) 259 { 260 throw new BuildException("There are no module data directories in "+ 261 this.datadir+"."); 262 } 263 264 String indicies[] = this.logdir.list(); 265 if (indicies == null) 266 { 267 indicies = new String [0]; 268 } 269 int count = modules.length; 270 271 for (int i = 0; i <= count; ++i) 272 { 273 String dirname = Integer.toString(i); 274 boolean found = false; 275 for (int j = 0; j < indicies.length; ++j) 276 { 277 if (indicies[j].equals( dirname )) 278 { 279 found = true; 280 break; 281 } 282 } 283 if (!found) 284 { 285 File f = new File ( this.logdir, dirname ); 286 f.mkdirs(); 287 } 288 } 289 } 290 291 292 private Element createReport( IAnalysisModule am, 293 AnalysisModuleData amd, IReportGenerator rg ) 294 throws IOException , BuildException 295 { 296 log( "Creating coverage report for module "+am.getMeasureName(), 297 Project.MSG_INFO ); 298 File outfile = createReportFile( am ); 299 FileOutputStream fos = new FileOutputStream ( outfile ); 300 Element ret = null; 301 try 302 { 303 ret = rg.createReport( am, amd ); 304 OutputStreamWriter osw = new OutputStreamWriter ( fos, "UTF8" ); 305 (new OutputXml()).write( ret, osw, null ); 306 } 307 catch (IllegalArgumentException iae) 308 { 309 311 iae.printStackTrace(); 314 log( iae.getMessage(), Project.MSG_WARN ); 315 ret = null; 316 } 317 finally 318 { 319 fos.close(); 320 } 321 322 return ret; 323 } 324 325 326 private File createReportFile( IAnalysisModule am ) 327 { 328 File f = new File ( this.outdir, this.prefix + am.getMeasureName() + 329 this.postfix ); 330 log( "Creating report file '"+f+"' for measure '"+am.getMeasureName()+ 331 "'.", Project.MSG_VERBOSE ); 332 return f; 333 } 334 335 336 private IChannelLogReader createChannelLogReader( IAnalysisModule am, 337 AnalysisModuleSet ams ) 338 throws IOException 339 { 340 short mi = ams.getAnalysisModuleIndex( am ); 341 IChannelLogReader clr = new DirectoryChannelLogReader( this.logdir, 342 mi ); 343 return clr; 344 } 345 346 347 private IMetaDataReader createMetaDataReader() 348 throws BuildException 349 { 350 try 351 { 352 return new DirMetaDataReader( this.datadir ); 353 } 354 catch (IOException e) 355 { 356 throw new BuildException( "I/O error creating meta-data reader.", 357 e, getLocation() ); 358 } 359 } 360 361 362 private void processStyles( Document doc, String moduleName ) 363 throws BuildException, IOException 364 { 365 Enumeration e = singleReports.elements(); 366 while (e.hasMoreElements()) 367 { 368 IReportStyle rs = (IReportStyle)e.nextElement(); 369 rs.generateReport( getProject(), doc, moduleName ); 370 } 371 } 372 373 374 private void finishStyles( Vector reports ) 375 throws BuildException, IOException 376 { 377 Enumeration e = singleReports.elements(); 378 while (e.hasMoreElements()) 379 { 380 IReportStyle rs = (IReportStyle)e.nextElement(); 381 rs.reportComplete( getProject(), new Vector () ); 382 } 383 e = null; 384 385 Document docs[] = new Document [ reports.size() ]; 387 reports.copyInto( docs ); 388 XmlCombinedReportGenerator gen = new XmlCombinedReportGenerator(); 389 log( "Creating combined coverage report", Project.MSG_INFO ); 390 File outfile = new File ( this.outdir, this.prefix + "all" + 391 this.postfix ); 392 log( "Creating report file '"+outfile+"' for all measures.", 393 Project.MSG_VERBOSE ); 394 FileOutputStream fos = new FileOutputStream ( outfile ); 395 Element ret = null; 396 try 397 { 398 ret = gen.createReport( docs ); 399 OutputStreamWriter osw = new OutputStreamWriter ( fos, "UTF8" ); 400 (new OutputXml()).write( ret, osw, null ); 401 } 402 catch (IllegalArgumentException iae) 403 { 404 406 iae.printStackTrace(); 409 log( iae.getMessage(), Project.MSG_WARN ); 410 ret = null; 411 } 412 finally 413 { 414 fos.close(); 415 } 416 docs = null; 417 reports.removeAllElements(); 418 reports = null; 419 420 if (ret != null) 422 { 423 Document doc = ret.getOwnerDocument(); 424 e = comboReports.elements(); 425 while (e.hasMoreElements()) 426 { 427 IReportStyle rs = (IReportStyle)e.nextElement(); 428 rs.generateReport( getProject(), doc, "all" ); 429 } 431 } 432 e = comboReports.elements(); 433 while (e.hasMoreElements()) 434 { 435 IReportStyle rs = (IReportStyle)e.nextElement(); 436 rs.reportComplete( getProject(), new Vector () ); 437 } 438 } 439 } 440 441 | Popular Tags |