1 23 24 package org.hammurapi; 25 26 import java.io.File ; 27 import java.io.FileInputStream ; 28 import java.io.FileNotFoundException ; 29 import java.io.FileOutputStream ; 30 import java.io.IOException ; 31 import java.io.InputStream ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.StringTokenizer ; 36 37 import org.apache.tools.ant.BuildException; 38 import org.apache.tools.ant.Project; 39 import org.apache.tools.ant.util.FileUtils; 40 import org.hammurapi.render.dom.CompositeResultsRenderer; 41 import org.hammurapi.render.dom.HammurapiMetricRenderer; 42 import org.hammurapi.render.dom.InspectorDescriptorRenderer; 43 import org.hammurapi.render.dom.InspectorSetRenderer; 44 import org.hammurapi.render.dom.InspectorSummaryRenderer; 45 import org.hammurapi.render.dom.ReportRenderer; 46 import org.hammurapi.render.dom.ReviewResultsRenderer; 47 import org.hammurapi.results.AggregatedResults; 48 import org.hammurapi.results.Annotation; 49 import org.hammurapi.results.AnnotationConfig; 50 import org.hammurapi.results.AnnotationContext; 51 import org.hammurapi.results.CompositeResults; 52 import org.hammurapi.results.InspectorSummary; 53 import org.hammurapi.results.ReportMixer; 54 import org.hammurapi.results.ReviewResults; 55 56 import com.pavelvlasov.config.ConfigurationException; 57 import com.pavelvlasov.metrics.MeasurementCategoryFactory; 58 import com.pavelvlasov.metrics.Metric; 59 import com.pavelvlasov.metrics.TimeIntervalCategory; 60 import com.pavelvlasov.render.RenderRequest; 61 import com.pavelvlasov.render.RenderingException; 62 import com.pavelvlasov.render.dom.AbstractRenderer; 63 64 71 public class Output implements Listener { 72 private String dir; 73 private boolean embeddedStyle=true; 74 private String extension=".html"; 75 private TaskBase task; 76 77 public Output(TaskBase task) { 78 this.task=task; 79 } 80 81 85 public void setDir(String dir) { 86 this.dir=dir; 87 } 88 89 private Map styleSheets=new HashMap (); 90 91 { 92 styleSheets.put("compilation-unit", new StyleSheetEntry()); 93 styleSheets.put("summary", new StyleSheetEntry()); 94 styleSheets.put("left-panel", new StyleSheetEntry()); 95 styleSheets.put("waived-violations", new StyleSheetEntry()); 96 styleSheets.put("package", new StyleSheetEntry()); 97 styleSheets.put("inspector-set", new StyleSheetEntry()); 98 styleSheets.put("inspector-descriptor", new StyleSheetEntry()); 99 styleSheets.put("inspector-summary", new StyleSheetEntry()); 100 styleSheets.put("metric-details", new StyleSheetEntry()); 101 } 102 103 public void addConfiguredStyleSheet(StyleSheetEntry styleSheet) { 104 if (styleSheet.getName()==null) { 105 throw new BuildException("Unnamed stylesheet"); 106 } 107 108 StyleSheetEntry existing=(StyleSheetEntry) styleSheets.get(styleSheet.getName()); 109 if (existing==null) { 110 throw new BuildException("Invalid stylesheet name: "+styleSheet.getName()); 111 } 112 113 if (styleSheet.getFile()!=null) { 114 existing.setFile(styleSheet.getFile()); 115 } 116 117 if (styleSheet.getUrl()!=null) { 118 existing.setUrl(styleSheet.getUrl()); 119 } 120 121 existing.setParameters(styleSheet.getParameters()); 122 } 123 124 129 public void setEmbeddedStyle(boolean embeddedStyle) { 130 this.embeddedStyle=embeddedStyle; 131 } 132 133 137 public void setExtension(String extension) { 138 this.extension=extension; 139 } 140 141 private File javaDocDir; 142 143 147 public void setJavaDocDir(File javaDocDir) { 148 this.javaDocDir=javaDocDir; 149 } 150 151 private File getOutDir() throws HammurapiException { 152 File outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir); 153 if (!outDir.exists()) { 154 throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath()); 155 } 156 157 if (!outDir.isDirectory()) { 158 throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath()); 159 } 160 161 return outDir; 162 } 163 164 private String getFileName(ReviewResults reviewResult) { 165 String packageName=reviewResult.getCompilationUnit().getPackage().getName(); 166 String unitName=reviewResult.getName(); 167 return "source/"+packageName.replace('.', '/')+'/'+unitName; 168 } 169 170 private File getFile(ReviewResults reviewResult) throws HammurapiException { 171 return new File (getOutDir(), getFileName(reviewResult)+extension); 172 } 173 174 private static final Object mkDirSynchronizationMonitor=new Object (); 175 176 public void onReview(ReviewResults reviewResult) throws HammurapiException { 177 if (dir==null) { 178 throw new HammurapiException("dir attribute is mandatory"); 179 } 180 181 final File outFile=getFile(reviewResult); 182 final File outFileParent=outFile.getParentFile(); 183 synchronized (mkDirSynchronizationMonitor) { 184 if (!outFileParent.exists()) { 185 if (!outFileParent.mkdirs()) { 186 throw new HammurapiException("Can't create "+outFileParent.getAbsolutePath()); 187 } 188 } 189 } 190 191 String packageName=reviewResult.getCompilationUnit().getPackage().getName(); 192 int count=0; 193 for (int i=0; i<packageName.length(); i++) { 194 if ('.'==packageName.charAt(i)) { 195 count++; 196 } 197 } 198 199 StringBuffer inspectorsPath=new StringBuffer ("../"); 200 while (count-->=0) { 201 inspectorsPath.append("../"); 202 } 203 204 renderAnnotations(reviewResult, outFile); 205 206 writeUnitDoc(reviewResult, outFile, inspectorsPath.toString(), getJavaDocPath(reviewResult)); 207 } 208 209 214 private void renderAnnotations(AggregatedResults reviewResult, final File outFile) throws HammurapiException { 215 Iterator ait=reviewResult.getAnnotations().iterator(); 216 while (ait.hasNext()) { 217 final Annotation annotation=(Annotation) ait.next(); 218 annotation.render(new AnnotationContext() { 219 public FileEntry getNextFile(String extension) throws HammurapiException { 220 try { 221 final File ret=File.createTempFile(outFile.getName()+"_"+annotation.getName(),extension,outFile.getParentFile()); 222 return new AnnotationContext.FileEntry() { 223 public File getFile() { 224 return ret; 225 } 226 227 public String getPath() { 228 return ret.getName(); 229 } 230 }; 231 } catch (IOException e) { 232 throw new HammurapiException(e); 233 } 234 } 235 236 public String getExtension() { 237 return Output.this.getExtension(); 238 } 239 240 public Object getParameter(String name) throws BuildException { 241 AnnotationConfig ac=(AnnotationConfig) annotationConfigs.get(annotation.getName()); 242 if (ac==null) { 243 return null; 244 } 245 246 return ac.getParameter(name); 247 } 248 249 public boolean isEmbeddedStyle() { 250 return Output.this.isEmbeddedStyle(); 251 } 252 }); 253 } 254 } 255 256 private String getRelativePath(String packageName) throws HammurapiException { 257 if (javaDocDir==null) { 258 return null; 259 } 260 261 try { 262 StringTokenizer ost=new StringTokenizer (getOutDir().getCanonicalPath(), File.separator); 263 StringTokenizer jst=new StringTokenizer (javaDocDir.getCanonicalPath(), File.separator); 264 StringBuffer upPath=new StringBuffer ("../"); 265 StringBuffer downPath=new StringBuffer (); 266 while (ost.hasMoreTokens() && jst.hasMoreTokens()) { 267 String ot=ost.nextToken(); 268 String jt=jst.nextToken(); 269 if (!ot.equals(jt)) { 270 upPath.append("../"); 271 downPath.append(jt); 272 downPath.append("/"); 273 break; 274 } 275 } 276 277 while (ost.hasMoreTokens()) { 278 upPath.append("../"); 279 ost.nextToken(); 280 } 281 282 while (jst.hasMoreTokens()) { 283 downPath.append(jst.nextToken()); 284 downPath.append("/"); 285 } 286 287 StringTokenizer pst=new StringTokenizer (packageName, "."); 288 while (pst.hasMoreTokens()) { 289 upPath.append("../"); 290 downPath.append(pst.nextToken()); 291 downPath.append("/"); 292 } 293 294 upPath.append(downPath); 295 return upPath.toString(); 296 } catch (IOException e) { 297 return null; 298 } 299 } 300 301 private String getRelativePath() throws HammurapiException { 302 if (javaDocDir==null) { 303 return null; 304 } 305 306 try { 307 StringTokenizer ost=new StringTokenizer (getOutDir().getCanonicalPath(), File.separator); 308 StringTokenizer jst=new StringTokenizer (javaDocDir.getCanonicalPath(), File.separator); 309 StringBuffer upPath=new StringBuffer (); 310 StringBuffer downPath=new StringBuffer (); 311 while (ost.hasMoreTokens() && jst.hasMoreTokens()) { 312 String ot=ost.nextToken(); 313 String jt=jst.nextToken(); 314 if (!ot.equals(jt)) { 315 upPath.append("../"); 316 downPath.append(jt); 317 downPath.append("/"); 318 break; 319 } 320 } 321 322 while (ost.hasMoreTokens()) { 323 upPath.append("../"); 324 ost.nextToken(); 325 } 326 327 while (jst.hasMoreTokens()) { 328 downPath.append(jst.nextToken()); 329 downPath.append("/"); 330 } 331 332 upPath.append(downPath); 333 return upPath.toString(); 334 } catch (IOException e) { 335 return null; 336 } 337 } 338 339 342 private String getJavaDocPath(ReviewResults ru) throws HammurapiException { 343 if (javaDocDir==null) { 344 return null; 345 } 346 347 if (!javaDocDir.exists()) { 348 throw new HammurapiException("JavaDoc directory does not exist"); 349 } 350 351 String packageName = ru.getCompilationUnit().getPackage().getName(); 352 String path=getRelativePath(packageName); 353 if (path==null) { 354 path=javaDocDir.getAbsolutePath()+'/'+packageName.replace('.', '/')+"/"; 355 } 356 357 return path; 358 } 359 360 363 private String getJavaDocPath(CompositeResults packageResults) throws HammurapiException { 364 if (javaDocDir==null) { 365 return null; 366 } 367 368 if (!javaDocDir.exists()) { 369 throw new HammurapiException("JavaDoc directory does not exist"); 370 } 371 372 String path=getRelativePath(packageResults.getName()); 373 if (path==null) { 374 path=javaDocDir.getAbsolutePath()+'/'+packageResults.getName().replace('.', '/')+'/'; 375 } 376 377 return path+"package-summary.html"; 378 } 379 380 private static TimeIntervalCategory tic=MeasurementCategoryFactory.getTimeIntervalCategory(Output.class); 381 382 private void render(AbstractRenderer renderer, String styleName, String inspectorsPath, String javaDocPath, File outFile) 383 throws HammurapiException { 384 long start=tic.getTime(); 385 File outFileParent=outFile.getParentFile(); 386 if (!outFileParent.exists()) { 387 if (!outFileParent.mkdirs()) { 388 throw new HammurapiException("Can't create "+outFileParent.getAbsolutePath()); 389 } 390 } 391 392 renderer.setEmbeddedStyle(embeddedStyle); 393 394 StyleSheetEntry sse=(StyleSheetEntry) styleSheets.get(styleName); 395 if (sse==null) { 396 throw new HammurapiException("Stylesheet entry with name '"+styleName +"' not found"); 397 } 398 399 try { 400 sse.setParameters(task.getProject(), renderer); 401 } catch (ConfigurationException ce) { 402 throw new HammurapiException("setParameters() failed", ce); 403 } 404 405 if (inspectorsPath!=null) { 406 renderer.setParameter("inspectorsPath", inspectorsPath); 407 } 408 409 if (javaDocPath!=null) { 410 renderer.setParameter("javaDocPath", javaDocPath); 411 } 412 413 try { 414 if (sse.getFile()==null) { 415 renderer.render(new FileOutputStream (outFile)); 416 } else { 417 renderer.render(new FileInputStream (sse.getFile()), new FileOutputStream (outFile)); 418 } 419 } catch (FileNotFoundException e) { 420 throw new HammurapiException(e.toString(), e); 421 } catch (RenderingException e) { 422 throw new HammurapiException(e.toString(), e); 423 } 424 tic.addInterval("render", start); 425 } 426 427 private void writeUnitDoc(ReviewResults reviewResult, File outFile, String inspectorsPath, String javaDocPath) throws HammurapiException { 428 task.getProject().log("Writing "+outFile.getAbsolutePath(), Project.MSG_VERBOSE); 429 render(new ReviewResultsRenderer(new RenderRequest(reviewResult)), "compilation-unit", inspectorsPath, javaDocPath, outFile); 430 } 431 432 public void onSummary(CompositeResults summary, InspectorSet inspectorSet) throws HammurapiException { 433 if (dir==null) { 434 throw new HammurapiException("dir attribute is mandatory"); 435 } 436 437 File outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir); 438 if (!outDir.exists()) { 439 throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath()); 440 } 441 442 if (!outDir.isDirectory()) { 443 throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath()); 444 } 445 446 String javaDocPath=javaDocDir==null ? null : getRelativePath()+"index.html"; 447 File summaryFile = new File (outDir, "summary"+extension); 448 renderAnnotations(summary, summaryFile); 449 RenderRequest summaryRenderRequest = new RenderRequest(ReportMixer.mix(summary, task.reviewDescription)); 450 render(new ReportRenderer(summaryRenderRequest, null), "summary", null, javaDocPath, summaryFile); 451 render(new CompositeResultsRenderer(summaryRenderRequest, "leftPanel"), "left-panel", null, javaDocPath, new File (outDir, "leftPanel"+extension)); 452 render(new CompositeResultsRenderer(summaryRenderRequest, "waivedViolations"), "waived-violations", null, javaDocPath, new File (outDir, "waivedViolations"+extension)); 453 render(new InspectorSetRenderer(new RenderRequest(inspectorSet)), "inspector-set", null, null, new File (outDir, "inspectors"+extension)); 454 455 Iterator descriptors=inspectorSet.getDescriptors().iterator(); 456 while (descriptors.hasNext()) { 457 InspectorDescriptor d =(InspectorDescriptor) descriptors.next(); 458 render(new InspectorDescriptorRenderer(new RenderRequest(d)), "inspector-descriptor", null, null, new File (outDir, "inspectors/inspector_" + d.getName() + extension)); 459 } 460 461 if (".HTML".equalsIgnoreCase(extension)) { 462 writeFrame(outDir); 463 } 464 465 Iterator it=summary.getSeveritySummary().values().iterator(); 466 while (it.hasNext()) { 467 Iterator iit=((Map ) it.next()).values().iterator(); 468 while (iit.hasNext()) { 469 InspectorSummary is=(InspectorSummary) iit.next(); 470 if (is.getLocations()!=null) { 471 render(new InspectorSummaryRenderer(new RenderRequest(is)), "inspector-summary", "source/", null, new File (outDir, "summary_"+is.getName()+extension)); 472 } 473 } 474 } 475 476 it=summary.getMetrics().values().iterator(); 477 while (it.hasNext()) { 478 Metric metric = (Metric) it.next(); 479 if (metric.getMeasurements()!=null) { 480 render(new HammurapiMetricRenderer(new RenderRequest(metric)), "metric-details", "source/", null, new File (outDir, "metric_details_"+metric.getName()+extension)); 481 } 482 } 483 } 484 485 private void writeFrame(File outDir) throws HammurapiException { 486 try { 487 byte[] buf=new byte[4096]; 488 String resourceName="/"+getClass().getName().replace('.', '/')+"!report.html"; 489 InputStream in=getClass().getResourceAsStream(resourceName); 490 if (in!=null) { 491 FileOutputStream out=new FileOutputStream (new File (outDir, "report.html")); 492 int l; 493 while ((l=in.read(buf))!=-1) { 494 out.write(buf,0,l); 495 } 496 out.close(); 497 in.close(); 498 } 499 } catch (IOException e) { 500 throw new HammurapiException("Can't write report.html: "+e); 501 } 502 } 503 504 public void onPackage(CompositeResults packageResults) throws HammurapiException { 505 if (dir==null) { 506 throw new HammurapiException("dir attribute is mandatory"); 507 } 508 509 File outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir); 510 if (!outDir.exists()) { 511 throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath()); 512 } 513 514 if (!outDir.isDirectory()) { 515 throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath()); 516 } 517 518 String summaryPath="source/"+packageResults.getName().replace('.', '/')+"/.summary"; 519 520 int count=0; 521 for (int i=0; i<summaryPath.length(); i++) { 522 if ('/'==summaryPath.charAt(i)) { 523 count++; 524 } 525 } 526 527 StringBuffer inspectorsPath=new StringBuffer (); 528 while (count-- > 0) { 529 inspectorsPath.append("../"); 530 } 531 532 File packageSummaryFile = new File (outDir, summaryPath+extension); 533 renderAnnotations(packageResults, packageSummaryFile); 534 render(new CompositeResultsRenderer(new RenderRequest(packageResults), "packageSummary"), "package", inspectorsPath.toString(), getJavaDocPath(packageResults), packageSummaryFile); 535 536 Iterator it=packageResults.getSeveritySummary().values().iterator(); 537 while (it.hasNext()) { 538 Iterator iit=((Map ) it.next()).values().iterator(); 539 while (iit.hasNext()) { 540 InspectorSummary is=(InspectorSummary) iit.next(); 541 if (is.getLocations()!=null) { 542 render(new InspectorSummaryRenderer(new RenderRequest(is)), "inspector-summary", inspectorsPath.toString()+"source/", null, new File (outDir, summaryPath+"_"+is.getName()+extension)); 543 } 544 } 545 } 546 547 it=packageResults.getMetrics().values().iterator(); 548 while (it.hasNext()) { 549 Metric metric = (Metric) it.next(); 550 if (metric.getMeasurements()!=null) { 551 render(new HammurapiMetricRenderer(new RenderRequest(metric)), "metric-details", inspectorsPath.toString()+"source/", null, new File (outDir, summaryPath+"_metric_details_"+metric.getName()+extension)); 552 } 553 } 554 } 555 556 private final Map annotationConfigs=new HashMap (); 557 558 563 public void addConfiguredAnnotationConfig(AnnotationConfig annotationConfig) { 564 annotationConfigs.put(annotationConfig.getName(), annotationConfig); 565 } 566 569 private String getExtension() { 570 return extension; 571 } 572 573 576 private boolean isEmbeddedStyle() { 577 return embeddedStyle; 578 } 579 580 public void onBegin(InspectorSet inspectorSet) throws HammurapiException { 581 File outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir); 582 if (!outDir.exists()) { 583 if (!outDir.mkdirs()) { 584 throw new HammurapiException("Output directory cannot be created: "+outDir.getAbsolutePath()); 585 } 586 } 587 588 if (!outDir.isDirectory()) { 589 throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath()); 590 } 591 } 592 } 593 | Popular Tags |