1 package org.codehaus.mojo.dashboard.report.plugin;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.IOException;
20 import java.text.SimpleDateFormat;
21 import java.util.Collections;
22 import java.util.Date;
23 import java.util.Hashtable;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.ResourceBundle;
28 import java.util.Set;
29
30 import org.apache.maven.plugin.logging.Log;
31
32 import org.codehaus.doxia.sink.Sink;
33 import org.codehaus.mojo.dashboard.report.plugin.beans.CheckstyleError;
34 import org.codehaus.mojo.dashboard.report.plugin.beans.CheckstyleReportBean;
35 import org.codehaus.mojo.dashboard.report.plugin.beans.CloverReportBean;
36 import org.codehaus.mojo.dashboard.report.plugin.beans.CoberturaReportBean;
37 import org.codehaus.mojo.dashboard.report.plugin.beans.CpdReportBean;
38 import org.codehaus.mojo.dashboard.report.plugin.beans.DashBoardMavenProject;
39 import org.codehaus.mojo.dashboard.report.plugin.beans.FindBugsReportBean;
40 import org.codehaus.mojo.dashboard.report.plugin.beans.IDashBoardReportBean;
41 import org.codehaus.mojo.dashboard.report.plugin.beans.JDependReportBean;
42 import org.codehaus.mojo.dashboard.report.plugin.beans.PmdReportBean;
43 import org.codehaus.mojo.dashboard.report.plugin.beans.SurefireReportBean;
44 import org.codehaus.mojo.dashboard.report.plugin.beans.TagListReportBean;
45 import org.codehaus.mojo.dashboard.report.plugin.beans.XRefPackageBean;
46 import org.codehaus.mojo.dashboard.report.plugin.beans.comparator.DescNbErrorCheckstyleComparator;
47 import org.codehaus.mojo.dashboard.report.plugin.chart.BarChartRenderer;
48 import org.codehaus.mojo.dashboard.report.plugin.chart.CheckstyleErrorsPieChartStrategy;
49 import org.codehaus.mojo.dashboard.report.plugin.chart.CheckstylePieChartStrategy;
50 import org.codehaus.mojo.dashboard.report.plugin.chart.CloverBarChartStrategy;
51 import org.codehaus.mojo.dashboard.report.plugin.chart.CoberturaBarChartStrategy;
52 import org.codehaus.mojo.dashboard.report.plugin.chart.FindbugsCategoriesPieChartStrategy;
53 import org.codehaus.mojo.dashboard.report.plugin.chart.FindbugsPrioritiesPieChartStrategy;
54 import org.codehaus.mojo.dashboard.report.plugin.chart.IChartRenderer;
55 import org.codehaus.mojo.dashboard.report.plugin.chart.PieChart3DRenderer;
56 import org.codehaus.mojo.dashboard.report.plugin.chart.PieChartRenderer;
57 import org.codehaus.mojo.dashboard.report.plugin.chart.SurefirePieChartStrategy;
58 import org.codehaus.mojo.dashboard.report.plugin.chart.TaglistPieChartStrategy;
59 import org.codehaus.mojo.dashboard.report.plugin.utils.ChartUtils;
60
61
62
63
64
65
66
67
68
69
70
71 public class DashBoardReportGenerator extends AbstractDashBoardGenerator
72 {
73
74
75
76 private static final int SPECIFIC_WIDTH = 600;
77
78
79
80
81 private final DashBoardMavenProject mavenProject;
82
83 private final Map map = new Hashtable();
84
85 private boolean isDBAvailable = false;
86
87 private boolean generateGraphs = true;
88
89
90
91
92 private boolean summary = false;
93
94 public DashBoardReportGenerator( DashBoardMavenProject mavenProject, boolean summary, boolean isDBAvailable,
95 boolean generateGraphs, Log log )
96 {
97 super( log );
98 this.mavenProject = mavenProject;
99 this.summary = summary;
100 this.isDBAvailable = isDBAvailable;
101 this.generateGraphs = generateGraphs;
102 Set reports = mavenProject.getReports();
103 Iterator iter = reports.iterator();
104 while ( iter.hasNext() )
105 {
106 IDashBoardReportBean report = (IDashBoardReportBean) iter.next();
107 if ( report != null )
108 {
109 this.map.put( report.getClass(), report );
110 }
111 }
112
113 }
114
115 public void doGenerateReport( ResourceBundle bundle, Sink sink )
116 {
117
118 this.createTitle( bundle, sink );
119 addDashboardCss(sink);
120 sink.body();
121 sink.anchor( "top" );
122 sink.anchor_();
123 this.createHeader( bundle, sink );
124
125 if ( this.map.get( CoberturaReportBean.class ) != null )
126 {
127 this.createCoberturaSection( bundle, sink, (CoberturaReportBean) this.map.get( CoberturaReportBean.class ) );
128 }
129 if ( this.map.get( CloverReportBean.class ) != null )
130 {
131 this.createCloverSection( bundle, sink, (CloverReportBean) this.map.get( CloverReportBean.class ) );
132 }
133 if ( this.map.get( SurefireReportBean.class ) != null )
134 {
135 this.createSurefireSection( bundle, sink, (SurefireReportBean) this.map.get( SurefireReportBean.class ) );
136 }
137 if ( this.map.get( CheckstyleReportBean.class ) != null )
138 {
139 this.createCheckStyleSection( bundle, sink,
140 (CheckstyleReportBean) this.map.get( CheckstyleReportBean.class ) );
141 }
142 if ( this.map.get( PmdReportBean.class ) != null )
143 {
144 this.createPmdSection( bundle, sink, (PmdReportBean) this.map.get( PmdReportBean.class ) );
145 }
146 if ( this.map.get( CpdReportBean.class ) != null )
147 {
148 this.createCpdSection( bundle, sink, (CpdReportBean) this.map.get( CpdReportBean.class ) );
149 }
150 if ( this.map.get( FindBugsReportBean.class ) != null )
151 {
152 this.createFindBugsSection( bundle, sink, (FindBugsReportBean) this.map.get( FindBugsReportBean.class ) );
153 }
154 if ( this.map.get( JDependReportBean.class ) != null )
155 {
156 this.createJDependSection( bundle, sink, (JDependReportBean) this.map.get( JDependReportBean.class ) );
157 }
158 if ( this.map.get( TagListReportBean.class ) != null )
159 {
160 this.createTaglistSection( bundle, sink, (TagListReportBean) this.map.get( TagListReportBean.class ) );
161 }
162
163 sink.body_();
164
165 sink.flush();
166
167 sink.close();
168 }
169
170 public void createTitle( ResourceBundle bundle, Sink sink )
171 {
172 sink.head();
173 sink.title();
174 sink.text( bundle.getString( "dashboard.report.name" ) );
175 sink.title_();
176 sink.head_();
177 }
178
179 public void createHeader( ResourceBundle bundle, Sink sink )
180 {
181 sink.section1();
182
183 sink.sectionTitle1();
184 sink.text( bundle.getString( "dashboard.report.name" ) );
185 sink.sectionTitle1_();
186
187 sink.text( "Date Generated: " + new SimpleDateFormat().format( new Date( System.currentTimeMillis() ) ) );
188 sink.horizontalRule();
189
190 if ( this.summary )
191 {
192 sink.sectionTitle3();
193 sink.text( "[" );
194 sink.link( "dashboard-report-details.html" );
195 sink.text( "Detailed Dashboard" );
196 sink.link_();
197 sink.text( "]" );
198 sink.sectionTitle3_();
199 sink.horizontalRule();
200 }
201
202 if ( this.map.get( CoberturaReportBean.class ) != null )
203 {
204 sink.text( "[" );
205 sink.link( "#cobertura" );
206 sink.text( bundle.getString( "report.cobertura.header" ) );
207 sink.link_();
208 sink.text( "]" );
209 sink.lineBreak();
210 }
211 if ( this.map.get( CloverReportBean.class ) != null )
212 {
213 sink.text( "[" );
214 sink.link( "#clover" );
215 sink.text( bundle.getString( "report.clover.header" ) );
216 sink.link_();
217 sink.text( "]" );
218 sink.lineBreak();
219 }
220 if ( this.map.get( SurefireReportBean.class ) != null )
221 {
222 sink.text( "[" );
223 sink.link( "#surefire" );
224 sink.text( bundle.getString( "report.surefire.header" ) );
225 sink.link_();
226 sink.text( "]" );
227 sink.lineBreak();
228 }
229 if ( this.map.get( CheckstyleReportBean.class ) != null )
230 {
231 sink.text( "[" );
232 sink.link( "#checkstyle" );
233 sink.text( bundle.getString( "report.checkstyle.header" ) );
234 sink.link_();
235 sink.text( "]" );
236 sink.lineBreak();
237 }
238 if ( this.map.get( PmdReportBean.class ) != null )
239 {
240 sink.text( "[" );
241 sink.link( "#pmd" );
242 sink.text( bundle.getString( "report.pmd.header" ) );
243 sink.link_();
244 sink.text( "]" );
245 sink.lineBreak();
246 }
247 if ( this.map.get( CpdReportBean.class ) != null )
248 {
249 sink.text( "[" );
250 sink.link( "#cpd" );
251 sink.text( bundle.getString( "report.cpd.header" ) );
252 sink.link_();
253 sink.text( "]" );
254 sink.lineBreak();
255 }
256 if ( this.map.get( FindBugsReportBean.class ) != null )
257 {
258 sink.text( "[" );
259 sink.link( "#findbugs" );
260 sink.text( bundle.getString( "report.findbugs.header" ) );
261 sink.link_();
262 sink.text( "]" );
263 sink.lineBreak();
264 }
265 if ( this.map.get( JDependReportBean.class ) != null )
266 {
267 sink.text( "[" );
268 sink.link( "#jdepend" );
269 sink.text( bundle.getString( "report.xrefpackage.header" ) );
270 sink.link_();
271 sink.text( "]" );
272 sink.lineBreak();
273 }
274
275 if ( this.map.get( TagListReportBean.class ) != null )
276 {
277 sink.text( "[" );
278 sink.link( "#taglist" );
279 sink.text( bundle.getString( "report.taglist.header" ) );
280 sink.link_();
281 sink.text( "]" );
282 sink.lineBreak();
283 }
284
285 sink.horizontalRule();
286 sink.lineBreak();
287
288 if ( !this.generateGraphs )
289 {
290 sink.text( "[" + bundle.getString( "dashboard.report.generategraphs.disabled" ) + "]" );
291 sink.lineBreak();
292 }
293
294 sink.section1_();
295 }
296
297 public void createSurefireSection( ResourceBundle bundle, Sink sink, SurefireReportBean report )
298 {
299
300 sink.section1();
301
302 sink.sectionTitle2();
303 sink.anchor( "surefire" );
304 sink.anchor_();
305 if ( this.summary )
306 {
307 sink.link( "dashboard-report-details.html#surefire" );
308 sink.text( bundle.getString( "report.surefire.header" ) );
309 sink.link_();
310 }
311 else
312 {
313 sink.link( "./surefire-report.html" );
314 sink.text( bundle.getString( "report.surefire.header" ) );
315 sink.link_();
316 }
317 sink.sectionTitle2_();
318 this.linkToTopPage( sink );
319 sink.lineBreak();
320 if ( this.isDBAvailable )
321 {
322 this.linkToHistoricPage( sink, "surefire" );
323 }
324 sink.section1_();
325 sink.lineBreak();
326 sink.table();
327 sink.tableRow();
328
329 this.sinkHeader( sink, bundle.getString( "report.surefire.label.successrate" ) );
330
331 this.sinkHeader( sink, bundle.getString( "report.surefire.label.tests" ) );
332
333 this.sinkHeader( sink, bundle.getString( "report.surefire.label.errors" ) );
334
335 this.sinkHeader( sink, bundle.getString( "report.surefire.label.failures" ) );
336
337 this.sinkHeader( sink, bundle.getString( "report.surefire.label.skipped" ) );
338
339 this.sinkHeader( sink, bundle.getString( "report.surefire.label.time" ) );
340
341 sink.tableRow_();
342
343 if ( report != null )
344 {
345
346
347 sink.tableRow();
348
349 this.sinkCellPercentGraphic( sink, report.getSucessRate() / 100, "surefire" );
350
351 this.sinkCell( sink, Integer.toString( report.getNbTests() ) );
352
353 this.sinkCell( sink, Integer.toString( report.getNbErrors() ) );
354
355 this.sinkCell( sink, Integer.toString( report.getNbFailures() ) );
356
357 this.sinkCell( sink, Integer.toString( report.getNbSkipped() ) );
358
359 this.sinkCell( sink, Double.toString( report.getElapsedTime() ) );
360
361 sink.tableRow_();
362 }
363 else
364 {
365 sink.tableRow();
366
367 this.sinkCell( sink, "0" );
368
369 this.sinkCell( sink, "0" );
370
371 this.sinkCell( sink, "0" );
372
373 this.sinkCell( sink, "0" );
374
375 this.sinkCell( sink, "0" + "%" );
376
377 this.sinkCell( sink, "0" );
378
379 sink.tableRow_();
380 }
381
382 sink.table_();
383
384 sink.lineBreak();
385 if ( this.generateGraphs )
386 {
387 IChartRenderer chart =
388 new PieChartRenderer(
389 new SurefirePieChartStrategy( bundle, this.mavenProject.getProjectName(), report ),
390 DashBoardReportGenerator.SPECIFIC_WIDTH, ChartUtils.STANDARD_HEIGHT );
391 if ( !chart.isEmpty() )
392 {
393 String filename = this.replaceForbiddenChar( this.mavenProject.getProjectName() );
394 if ( this.summary )
395 {
396 filename += "_Summary_Surefire." + chart.getFileExtension();
397 }
398 else
399 {
400 filename += "_Surefire." + chart.getFileExtension();
401 }
402 filename = filename.replace( ' ', '_' );
403 String filenameWithPath = this.getImagesPath() + "/" + filename;
404 this.getLog().debug( "createSurefireGraph = " + filename );
405 try
406 {
407 chart.saveToFile( filenameWithPath );
408 String link = "images/" + filename;
409 link = link.replace( ' ', '_' );
410 sink.figure();
411 sink.figureGraphics( link );
412 sink.figure_();
413 }
414 catch ( IOException e )
415 {
416 this.getLog().debug( "createSurefireGraph exception = " + e.getMessage() );
417 }
418 }
419 }
420
421
422
423
424
425 }
426
427
428
429
430
431
432
433 public void createCloverSection( ResourceBundle bundle, Sink sink, CloverReportBean report )
434 {
435 sink.section1();
436
437 sink.sectionTitle2();
438 sink.anchor( "clover" );
439 sink.anchor_();
440 if ( this.summary )
441 {
442 sink.link( "dashboard-report-details.html#clover" );
443 sink.text( bundle.getString( "report.clover.header" ) );
444 sink.link_();
445 }
446 else
447 {
448 sink.link( "./clover/index.html" );
449 sink.text( bundle.getString( "report.clover.header" ) );
450 sink.link_();
451 }
452 sink.sectionTitle2_();
453 this.linkToTopPage( sink );
454 sink.lineBreak();
455 if ( this.isDBAvailable )
456 {
457 this.linkToHistoricPage( sink, "clover" );
458 }
459 sink.section1_();
460 sink.lineBreak();
461 sink.table();
462 sink.tableRow();
463
464 this.sinkHeader( sink, bundle.getString( "report.clover.label.total" ) );
465
466 this.sinkHeader( sink, bundle.getString( "report.clover.label.conditionals" ) );
467
468 this.sinkHeader( sink, bundle.getString( "report.clover.label.statements" ) );
469
470 this.sinkHeader( sink, bundle.getString( "report.clover.label.methods" ) );
471
472 sink.tableRow_();
473
474 if ( report != null )
475 {
476 sink.tableRow();
477
478 if ( this.generateGraphs )
479 {
480
481 this.sinkCell( sink, report.getElementsLabel() );
482
483 this.sinkCell( sink, report.getConditionalsLabel() );
484
485 this.sinkCell( sink, report.getStatementsLabel() );
486
487 this.sinkCell( sink, report.getMethodsLabel() );
488
489 }
490 else
491 {
492 sink.tableCell();
493 sinkPercentGraphic( sink, report.getPercentCoveredConditionals() );
494 sink.text( "(" + report.getCoveredElements() + " / " + report.getElements() + ")" );
495 sink.tableCell_();
496 sink.tableCell();
497 sinkPercentGraphic( sink, report.getPercentCoveredConditionals() );
498 sink.text( "(" + report.getCoveredConditionals() + " / " + report.getConditionals() + ")" );
499 sink.tableCell_();
500 sink.tableCell();
501 sinkPercentGraphic( sink, report.getPercentCoveredStatements() );
502 sink.text( "(" + report.getCoveredStatements() + " / " + report.getStatements() + ")" );
503 sink.tableCell_();
504 sink.tableCell();
505 sinkPercentGraphic( sink, report.getPercentCoveredMethods() );
506 sink.text( "(" + report.getCoveredMethods() + " / " + report.getMethods() + ")" );
507 sink.tableCell_();
508 }
509
510 sink.tableRow_();
511 }
512 else
513 {
514 sink.tableRow();
515
516 this.sinkCell( sink, "0" );
517
518 this.sinkCell( sink, "0" );
519
520 this.sinkCell( sink, "0" );
521
522 this.sinkCell( sink, "0" );
523
524 this.sinkCell( sink, "0" + "%" );
525
526 this.sinkCell( sink, "0" );
527
528 sink.tableRow_();
529 }
530 sink.table_();
531
532 sink.lineBreak();
533 if ( this.generateGraphs )
534 {
535 Map datas = new Hashtable();
536 datas.put( this.mavenProject.getProjectName(), report );
537 IChartRenderer chart =
538 new BarChartRenderer( new CloverBarChartStrategy( bundle, this.mavenProject.getProjectName(), datas ),
539 DashBoardReportGenerator.SPECIFIC_WIDTH + 50, ChartUtils.STANDARD_HEIGHT );
540 if ( !chart.isEmpty() )
541 {
542 String filename = this.replaceForbiddenChar( this.mavenProject.getProjectName() );
543 if ( this.summary )
544 {
545 filename += "_Summary_Clover." + chart.getFileExtension();
546 }
547 else
548 {
549 filename += "_Clover." + chart.getFileExtension();
550 }
551 filename = filename.replace( ' ', '_' );
552 String filenameWithPath = this.getImagesPath() + "/" + filename;
553 this.getLog().debug( "createCloverGraph = " + filename );
554 try
555 {
556 chart.saveToFile( filenameWithPath );
557 String link = "images/" + filename;
558 link = link.replace( ' ', '_' );
559 sink.figure();
560 sink.figureGraphics( link );
561 sink.figure_();
562 }
563 catch ( IOException e )
564 {
565 this.getLog().debug( "createCloverGraph exception = " + e.getMessage() );
566 }
567 }
568 }
569
570
571
572
573
574 }
575
576 public void createCoberturaSection( ResourceBundle bundle, Sink sink, CoberturaReportBean report )
577 {
578
579 sink.section1();
580
581 sink.sectionTitle2();
582 sink.anchor( "cobertura" );
583 sink.anchor_();
584 if ( this.summary )
585 {
586 sink.link( "dashboard-report-details.html#cobertura" );
587 sink.text( bundle.getString( "report.cobertura.header" ) );
588 sink.link_();
589 }
590 else
591 {
592 sink.link( "./cobertura/index.html" );
593 sink.text( bundle.getString( "report.cobertura.header" ) );
594 sink.link_();
595 }
596
597 sink.sectionTitle2_();
598 this.linkToTopPage( sink );
599 sink.lineBreak();
600 if ( this.isDBAvailable )
601 {
602 this.linkToHistoricPage( sink, "cobertura" );
603 }
604 sink.section1_();
605 sink.lineBreak();
606 if ( report == null )
607 {
608 sink.text( "Error: Unable to read from Cobertura data file ." );
609 }
610 else
611 {
612 sink.table();
613 sink.tableRow();
614
615 this.sinkHeader( sink, bundle.getString( "report.cobertura.label.nbclasses" ) );
616
617 this.sinkHeader( sink, bundle.getString( "report.cobertura.label.linecover" ) );
618
619 this.sinkHeader( sink, bundle.getString( "report.cobertura.label.branchcover" ) );
620
621 sink.tableRow_();
622
623 sink.tableRow();
624 this.sinkCell( sink, Integer.toString( report.getNbClasses() ) );
625
626 if ( this.generateGraphs )
627 {
628 this.sinkCell( sink, getPercentValue( report.getLineCoverRate() ) );
629 this.sinkCell( sink, getPercentValue( report.getBranchCoverRate() ) );
630 }
631 else
632 {
633 sinkCellPercentGraphic( sink, report.getLineCoverRate(), "cobertura" );
634 sinkCellPercentGraphic( sink, report.getBranchCoverRate(), "cobertura" );
635 }
636
637 sink.tableRow_();
638
639 sink.table_();
640 }
641 sink.lineBreak();
642 if ( this.generateGraphs )
643 {
644 Map datas = new Hashtable();
645 datas.put( this.mavenProject.getProjectName(), report );
646 IChartRenderer chart =
647 new BarChartRenderer(
648 new CoberturaBarChartStrategy( bundle, this.mavenProject.getProjectName(), datas ),
649 DashBoardReportGenerator.SPECIFIC_WIDTH + 50, ChartUtils.STANDARD_HEIGHT );
650 if ( !chart.isEmpty() )
651 {
652 String filename = this.replaceForbiddenChar( this.mavenProject.getProjectName() );
653 if ( this.summary )
654 {
655 filename += "_Summary_Cobertura." + chart.getFileExtension();
656 }
657 else
658 {
659 filename += "_Cobertura." + chart.getFileExtension();
660 }
661 filename = filename.replace( ' ', '_' );
662 String filenameWithPath = this.getImagesPath() + "/" + filename;
663 this.getLog().debug( "createCoberturaGraph = " + filename );
664 try
665 {
666 chart.saveToFile( filenameWithPath );
667 String link = "images/" + filename;
668 link = link.replace( ' ', '_' );
669 sink.figure();
670 sink.figureGraphics( link );
671 sink.figure_();
672 }
673 catch ( IOException e )
674 {
675 this.getLog().debug( "createCoberturaGraph exception = " + e.getMessage() );
676 }
677 }
678 }
679
680
681
682
683
684 }
685
686 public void createPmdSection( ResourceBundle bundle, Sink sink, PmdReportBean report )
687 {
688
689 sink.section1();
690
691 sink.sectionTitle2();
692 sink.anchor( "pmd" );
693 sink.anchor_();
694 if ( this.summary )
695 {
696 sink.link( "dashboard-report-details.html#pmd" );
697 sink.text( bundle.getString( "report.pmd.header" ) );
698 sink.link_();
699 }
700 else
701 {
702 sink.link( "./pmd.html" );
703 sink.text( bundle.getString( "report.pmd.header" ) );
704 sink.link_();
705 }
706
707 sink.sectionTitle2_();
708 this.linkToTopPage( sink );
709 sink.lineBreak();
710 if ( this.isDBAvailable )
711 {
712 this.linkToHistoricPage( sink, "pmd" );
713 }
714 sink.section1_();
715 sink.lineBreak();
716 if ( report == null )
717 {
718 sink.text( "Error: Unable to read from PMD data file ." );
719 }
720 else
721 {
722 sink.table();
723 sink.tableRow();
724
725 this.sinkHeader( sink, bundle.getString( "report.pmd.label.nbclasses" ) );
726
727 this.sinkHeader( sink, bundle.getString( "report.pmd.label.nbviolations" ) );
728
729 sink.tableRow_();
730
731 sink.tableRow();
732
733 this.sinkCell( sink, Integer.toString( report.getNbClasses() ) );
734
735 this.sinkCell( sink, Integer.toString( report.getNbViolations() ) );
736
737 sink.tableRow_();
738
739 sink.table_();
740 }
741 sink.lineBreak();
742 }
743
744 public void createCpdSection( ResourceBundle bundle, Sink sink, CpdReportBean report )
745 {
746
747 sink.section1();
748
749 sink.sectionTitle2();
750 sink.anchor( "cpd" );
751 sink.anchor_();
752 if ( this.summary )
753 {
754 sink.link( "dashboard-report-details.html#cpd" );
755 sink.text( bundle.getString( "report.cpd.header" ) );
756 sink.link_();
757 }
758 else
759 {
760 sink.link( "./cpd.html" );
761 sink.text( bundle.getString( "report.cpd.header" ) );
762 sink.link_();
763 }
764 sink.sectionTitle2_();
765 this.linkToTopPage( sink );
766 sink.lineBreak();
767 if ( this.isDBAvailable )
768 {
769 this.linkToHistoricPage( sink, "cpd" );
770 }
771 sink.section1_();
772 sink.lineBreak();
773 if ( report == null )
774 {
775 sink.text( "Error: Unable to read from CPD data file ." );
776 }
777 else
778 {
779 sink.table();
780 sink.tableRow();
781
782 this.sinkHeader( sink, bundle.getString( "report.cpd.label.nbclasses" ) );
783
784 this.sinkHeader( sink, bundle.getString( "report.cpd.label.nbduplicate" ) );
785
786 sink.tableRow_();
787
788 sink.tableRow();
789
790 this.sinkCell( sink, Integer.toString( report.getNbClasses() ) );
791
792 this.sinkCell( sink, Integer.toString( report.getNbDuplicate() ) );
793
794 sink.tableRow_();
795
796 sink.table_();
797 }
798 sink.lineBreak();
799 }
800
801 public void createCheckStyleSection( ResourceBundle bundle, Sink sink, CheckstyleReportBean report )
802 {
803
804 sink.section1();
805 sink.sectionTitle2();
806 sink.anchor( "checkstyle" );
807 sink.anchor_();
808 if ( this.summary )
809 {
810 sink.link( "dashboard-report-details.html#checkstyle" );
811 sink.text( bundle.getString( "report.checkstyle.header" ) );
812 sink.link_();
813 }
814 else
815 {
816 sink.link( "./checkstyle.html" );
817 sink.text( bundle.getString( "report.checkstyle.header" ) );
818 sink.link_();
819 }
820 sink.sectionTitle2_();
821 this.linkToTopPage( sink );
822 sink.lineBreak();
823 if ( this.isDBAvailable )
824 {
825 this.linkToHistoricPage( sink, "checkstyle" );
826 }
827 sink.section1_();
828 if ( report == null )
829 {
830 sink.text( "Error: Unable to read from checkstyle data file ." );
831 }
832 else
833 {
834 sink.table();
835
836 sink.tableRow();
837 sink.tableHeaderCell();
838 sink.text( bundle.getString( "report.checkstyle.files" ) );
839 sink.tableHeaderCell_();
840
841 sink.tableHeaderCell();
842 sink.text( bundle.getString( "report.checkstyle.column.total" ) );
843 sink.tableHeaderCell_();
844
845 sink.tableHeaderCell();
846 sink.text( bundle.getString( "report.checkstyle.column.infos" ) );
847 sink.nonBreakingSpace();
848 this.iconInfo( sink );
849 sink.tableHeaderCell_();
850
851 sink.tableHeaderCell();
852 sink.text( bundle.getString( "report.checkstyle.column.warnings" ) );
853 sink.nonBreakingSpace();
854 this.iconWarning( sink );
855 sink.tableHeaderCell_();
856
857 sink.tableHeaderCell();
858 sink.text( bundle.getString( "report.checkstyle.column.errors" ) );
859 sink.nonBreakingSpace();
860 this.iconError( sink );
861 sink.tableHeaderCell_();
862 sink.tableRow_();
863
864 sink.tableRow();
865
866 this.sinkCell( sink, Integer.toString( report.getNbClasses() ) );
867 this.sinkCell( sink, Integer.toString( report.getNbTotal() ) );
868
869 sink.tableCell();
870 sink.text( Integer.toString( report.getNbInfos() ) );
871 sinkInvertPercentGraphic( sink, report.getPercentInfos() );
872 sink.tableCell_();
873 sink.tableCell();
874 sink.text( Integer.toString( report.getNbWarnings() ) );
875 sinkInvertPercentGraphic( sink, report.getPercentWarnings() );
876 sink.tableCell_();
877 sink.tableCell();
878 sink.text( Integer.toString( report.getNbErrors() ) );
879 sinkInvertPercentGraphic( sink, report.getPercentErrors() );
880 sink.tableCell_();
881
882 sink.tableRow_();
883 sink.table_();
884 }
885 sink.lineBreak();
886 if ( this.generateGraphs )
887 {
888 IChartRenderer chart =
889 new PieChartRenderer( new CheckstylePieChartStrategy( bundle, this.mavenProject.getProjectName(),
890 report ),
891 DashBoardReportGenerator.SPECIFIC_WIDTH, ChartUtils.STANDARD_HEIGHT );
892 if ( !chart.isEmpty() )
893 {
894 String filename = this.replaceForbiddenChar( this.mavenProject.getProjectName() );
895 if ( this.summary )
896 {
897 filename += "_Summary_CheckStyle." + chart.getFileExtension();
898 }
899 else
900 {
901 filename += "_CheckStyle." + chart.getFileExtension();
902 }
903 filename = filename.replace( ' ', '_' );
904 String filenameWithPath = this.getImagesPath() + "/" + filename;
905 this.getLog().debug( "createCheckStyleGraph = " + filename );
906 try
907 {
908 chart.saveToFile( filenameWithPath );
909 String link = "images/" + filename;
910 link = link.replace( ' ', '_' );
911 sink.figure();
912 sink.figureGraphics( link );
913 sink.figure_();
914 }
915 catch ( IOException e )
916 {
917 this.getLog().debug( "createCheckStyleGraph exception = " + e.getMessage() );
918 }
919 }
920
921
922
923
924 IChartRenderer chartError =
925 new PieChart3DRenderer(
926 new CheckstyleErrorsPieChartStrategy(
927 bundle,
928 this.mavenProject.getProjectName()
929 + " "
930 + bundle.getString( "chart.checkstyle.violations.title" ),
931 report ), ChartUtils.STANDARD_WIDTH,
932 ChartUtils.STANDARD_HEIGHT );
933 sink.lineBreak();
934 sink.lineBreak();
935
936 if ( !chartError.isEmpty() )
937 {
938 String filename = this.replaceForbiddenChar( this.mavenProject.getProjectName() );
939 if ( this.summary )
940 {
941 filename += "_Summary_CheckStyle_Error." + chartError.getFileExtension();
942 }
943 else
944 {
945 filename += "_CheckStyle_Error." + chartError.getFileExtension();
946 }
947 filename = filename.replace( ' ', '_' );
948 String filenameWithPath = this.getImagesPath() + "/" + filename;
949 try
950 {
951 chartError.saveToFile( filenameWithPath );
952 String link = "images/" + filename;
953 link = link.replace( ' ', '_' );
954 sink.figure();
955 sink.figureGraphics( link );
956 sink.figure_();
957 }
958 catch ( IOException e )
959 {
960 this.getLog().debug( "createCheckStyleGraphError exception = " + e.getMessage() );
961 }
962 }
963 }
964 else
965 {
966
967 sink.sectionTitle3();
968 sink.text( this.mavenProject.getProjectName() + " "
969 + bundle.getString( "chart.checkstyle.violations.title" ) );
970 sink.sectionTitle3_();
971
972 double percentVal = 0;
973 int nbItInfPercent = 0;
974 CheckstyleError error = new CheckstyleError();
975 List errorsUnSorted = report.getErrors();
976 Collections.sort( errorsUnSorted, new DescNbErrorCheckstyleComparator() );
977 Iterator iterator = errorsUnSorted.iterator();
978 int total = report.getNbTotal();
979
980 sink.table();
981
982 sink.tableRow();
983 sink.tableHeaderCell();
984 sink.text( "Violations" );
985 sink.tableHeaderCell_();
986
987 sink.tableHeaderCell();
988 sink.text( "Rate" );
989 sink.tableHeaderCell_();
990
991 sink.tableRow_();
992
993 while ( iterator.hasNext() )
994 {
995 error = (CheckstyleError) iterator.next();
996 percentVal = (double) ( error.getNbIteration() * 1d / total );
997 if ( percentVal > 0.01d )
998 {
999 sink.tableRow();
1000 this.sinkCell( sink, error.getMessage() );
1001 this.sinkCellInvertPercentGraphic( sink, percentVal, "checkstyle" );
1002 sink.tableRow_();
1003 }
1004 else
1005 {
1006 nbItInfPercent += error.getNbIteration();
1007 }
1008 }
1009
1010 if ( nbItInfPercent > 0 )
1011 {
1012 percentVal = (double) ( nbItInfPercent * 1d / total );
1013 sink.tableRow();
1014 this.sinkCell( sink, bundle.getString( "chart.checkstyle.violations.others.label" ) );
1015 this.sinkCellInvertPercentGraphic( sink, percentVal, "checkstyle" );
1016 sink.tableRow_();
1017 }
1018
1019 sink.table_();
1020 }
1021
1022 }
1023
1024 public void createJDependSection( ResourceBundle bundle, Sink sink, JDependReportBean report )
1025 {
1026 this.getLog().debug( "createJDependSection creation." );
1027 sink.section1();
1028
1029 sink.sectionTitle2();
1030 sink.anchor( "jdepend" );
1031 sink.anchor_();
1032 if ( this.summary )
1033 {
1034 sink.link( "dashboard-report-details.html#jdepend" );
1035 sink.text( "Top " + this.getNbExportedPackagesSummary() + " "
1036 + bundle.getString( "report.xrefpackage.header" ) );
1037 sink.link_();
1038 }
1039 else
1040 {
1041 sink.link( "./jdepend-report.html" );
1042 sink.text( bundle.getString( "report.xrefpackage.header" ) );
1043 sink.link_();
1044 }
1045 sink.sectionTitle2_();
1046 this.linkToTopPage( sink );
1047 sink.lineBreak();
1048
1049 sink.section1_();
1050 sink.lineBreak();
1051 if ( report == null )
1052 {
1053 sink.text( "Error: Unable to read from Jdepend data file ." );
1054 }
1055 else
1056 {
1057 double averageAC = report.getAverageAfferentCoupling();
1058
1059 double calcul = ( Math.rint( averageAC * 1000 ) ) / 1000;
1060
1061 sink.sectionTitle3();
1062 sink.text( bundle.getString( "report.xrefpackage.label.average" ) + " = " + calcul );
1063 sink.lineBreak();
1064 sink.text( " Nb Packages = " + report.getNbPackages() );
1065 sink.sectionTitle3_();
1066 sink.table();
1067 sink.tableRow();
1068
1069 this.sinkHeader( sink, bundle.getString( "report.xrefpackage.label.package" ) );
1070
1071 this.sinkHeader( sink, bundle.getString( "report.xrefpackage.label.ac" ) );
1072
1073 this.sinkHeader( sink, bundle.getString( "report.xrefpackage.label.linecover" ) );
1074
1075 this.sinkHeader( sink, bundle.getString( "report.xrefpackage.label.branchcover" ) );
1076
1077 sink.tableRow_();
1078
1079 List pack = report.getPackages();
1080 Iterator iter = pack.iterator();
1081 boolean threshold = false;
1082 int nbPack = 0;
1083 while ( iter.hasNext() )
1084 {
1085 nbPack = nbPack + 1;
1086 XRefPackageBean bean = (XRefPackageBean) iter.next();
1087 Integer ac = bean.getAfferentCoupling();
1088 if ( ac.doubleValue() <= averageAC && !threshold )
1089 {
1090 threshold = true;
1091 sink.tableRow();
1092 this.sinkCellBold( sink, bundle.getString( "report.xrefpackage.label.threshold" ) );
1093 this.sinkCellBold( sink, String.valueOf( calcul ) );
1094
1095
1096 sink.tableRow_();
1097 }
1098 sink.tableRow();
1099 this.sinkCell( sink, bean.getPackageName() );
1100 this.sinkCell( sink, ac.toString() );
1101
1102 sinkCellPercentGraphic( sink, bean.getLineCoverRate(), "cobertura" );
1103
1104 sinkCellPercentGraphic( sink, bean.getBranchCoverRate(), "cobertura" );
1105 sink.tableRow_();
1106 if ( this.summary && nbPack >= this.getNbExportedPackagesSummary() )
1107 {
1108 break;
1109 }
1110 }
1111
1112 sink.table_();
1113 }
1114 sink.lineBreak();
1115 }
1116
1117 public void createFindBugsSection( ResourceBundle bundle, Sink sink, FindBugsReportBean report )
1118 {
1119
1120 sink.section1();
1121 sink.sectionTitle2();
1122 sink.anchor( "findbugs" );
1123 sink.anchor_();
1124 if ( this.summary )
1125 {
1126 sink.link( "dashboard-report-details.html#findbugs" );
1127 sink.text( bundle.getString( "report.findbugs.header" ) );
1128 sink.link_();
1129 }
1130 else
1131 {
1132 sink.link( "./findbugs.html" );
1133 sink.text( bundle.getString( "report.findbugs.header" ) );
1134 sink.link_();
1135 }
1136 sink.sectionTitle2_();
1137 this.linkToTopPage( sink );
1138 sink.lineBreak();
1139 if ( this.isDBAvailable )
1140 {
1141 this.linkToHistoricPage( sink, "findbugs" );
1142 }
1143 sink.section1_();
1144 if ( report == null )
1145 {
1146 sink.text( "Error: Unable to read from findbugs data file ." );
1147 }
1148 else
1149 {
1150 sink.table();
1151
1152 sink.tableRow();
1153 sink.tableHeaderCell();
1154 sink.text( bundle.getString( "report.findbugs.label.nbclasses" ) );
1155 sink.tableHeaderCell_();
1156
1157 sink.tableHeaderCell();
1158 sink.text( bundle.getString( "report.findbugs.label.nbbugs" ) );
1159 sink.tableHeaderCell_();
1160
1161 sink.tableHeaderCell();
1162 sink.text( bundle.getString( "report.findbugs.label.nberrors" ) );
1163 sink.tableHeaderCell_();
1164
1165 sink.tableHeaderCell();
1166 sink.text( bundle.getString( "report.findbugs.label.nbMissingClasses" ) );
1167 sink.tableHeaderCell_();
1168
1169 sink.tableRow_();
1170
1171 sink.tableRow();
1172
1173 this.sinkCell( sink, Integer.toString( report.getNbClasses() ) );
1174 this.sinkCell( sink, Integer.toString( report.getNbBugs() ) );
1175 this.sinkCell( sink, Integer.toString( report.getNbErrors() ) );
1176 this.sinkCell( sink, Integer.toString( report.getNbMissingClasses() ) );
1177
1178 sink.tableRow_();
1179
1180 sink.table_();
1181 }
1182 sink.lineBreak();
1183 if ( this.generateGraphs )
1184 {
1185 IChartRenderer chartError =
1186 new PieChart3DRenderer(
1187 new FindbugsCategoriesPieChartStrategy(
1188 bundle,
1189 this.mavenProject.getProjectName()
1190 + " "
1191 + bundle.getString( "chart.findbugs.bycategory.title" ),
1192 report ), ChartUtils.STANDARD_WIDTH,
1193 ChartUtils.STANDARD_HEIGHT );
1194 sink.lineBreak();
1195 sink.lineBreak();
1196
1197 if ( !chartError.isEmpty() )
1198 {
1199 String filename = this.replaceForbiddenChar( this.mavenProject.getProjectName() );
1200 if ( this.summary )
1201 {
1202 filename += "_Summary_Findbugs_Categories." + chartError.getFileExtension();
1203 }
1204 else
1205 {
1206 filename += "_Findbugs_Categories." + chartError.getFileExtension();
1207 }
1208 filename = filename.replace( ' ', '_' );
1209 String filenameWithPath = this.getImagesPath() + "/" + filename;
1210 try
1211 {
1212 chartError.saveToFile( filenameWithPath );
1213 String link = "images/" + filename;
1214 link = link.replace( ' ', '_' );
1215 sink.figure();
1216 sink.figureGraphics( link );
1217 sink.figure_();
1218 }
1219 catch ( IOException e )
1220 {
1221 this.getLog().debug( "createFindbugsCategoriesGraphError exception = " + e.getMessage() );
1222 }
1223 }
1224 sink.lineBreak();
1225 chartError =
1226 new PieChart3DRenderer(
1227 new FindbugsPrioritiesPieChartStrategy(
1228 bundle,
1229 this.mavenProject.getProjectName()
1230 + " "
1231 + bundle.getString( "chart.findbugs.bypriority.title" ),
1232 report ), ChartUtils.STANDARD_WIDTH,
1233 ChartUtils.STANDARD_HEIGHT );
1234 sink.lineBreak();
1235 sink.lineBreak();
1236
1237 if ( !chartError.isEmpty() )
1238 {
1239 String filename = this.replaceForbiddenChar( this.mavenProject.getProjectName() );
1240 if ( this.summary )
1241 {
1242 filename += "_Summary_Findbugs_Priorities." + chartError.getFileExtension();
1243 }
1244 else
1245 {
1246 filename += "_Findbugs_Priorities." + chartError.getFileExtension();
1247 }
1248 filename = filename.replace( ' ', '_' );
1249 String filenameWithPath = this.getImagesPath() + "/" + filename;
1250 try
1251 {
1252 chartError.saveToFile( filenameWithPath );
1253 String link = "images/" + filename;
1254 link = link.replace( ' ', '_' );
1255 sink.figure();
1256 sink.figureGraphics( link );
1257 sink.figure_();
1258 }
1259 catch ( IOException e )
1260 {
1261 this.getLog().debug( "createFindbugsPrioritiesGraphError exception = " + e.getMessage() );
1262 }
1263 }
1264 }
1265 else
1266 {
1267 sink.sectionTitle3();
1268 sink.text( this.mavenProject.getProjectName() + " " + bundle.getString( "chart.findbugs.bycategory.title" ) );
1269 sink.sectionTitle3_();
1270 sink.table();
1271 sink.tableRow();
1272 sink.tableHeaderCell();
1273 sink.text( "Categories" );
1274 sink.tableHeaderCell_();
1275
1276 sink.tableHeaderCell();
1277 sink.text( "Rate" );
1278 sink.tableHeaderCell_();
1279
1280 sink.tableRow_();
1281
1282 Map categories = report.getCategories();
1283 Iterator iterator = categories.keySet().iterator();
1284 while ( iterator.hasNext() )
1285 {
1286 String category = (String) iterator.next();
1287 Integer value = (Integer) categories.get( category );
1288 double percentVal = value.intValue() / (double) report.getNbBugs();
1289
1290 sink.tableRow();
1291 this.sinkCell( sink, category );
1292 this.sinkCellInvertPercentGraphic( sink, percentVal, "findbugs" );
1293 sink.tableRow_();
1294 }
1295 sink.table_();
1296 sink.lineBreak();
1297
1298 sink.sectionTitle3();
1299 sink.text( this.mavenProject.getProjectName() + " " + bundle.getString( "chart.findbugs.bypriority.title" ) );
1300 sink.sectionTitle3_();
1301 sink.table();
1302 sink.tableRow();
1303 sink.tableHeaderCell();
1304 sink.text( "Priorities" );
1305 sink.tableHeaderCell_();
1306
1307 sink.tableHeaderCell();
1308 sink.text( "Rate" );
1309 sink.tableHeaderCell_();
1310
1311 sink.tableRow_();
1312
1313 Map priorities = report.getPriorities();
1314 Iterator iteratorP = priorities.keySet().iterator();
1315 while ( iteratorP.hasNext() )
1316 {
1317 String priority = (String) iteratorP.next();
1318 Integer value = (Integer) priorities.get( priority );
1319 double percentVal = value.intValue() / (double) report.getNbBugs();
1320
1321 sink.tableRow();
1322 this.sinkCell( sink, priority );
1323 this.sinkCellInvertPercentGraphic( sink, percentVal, "findbugs" );
1324 sink.tableRow_();
1325 }
1326 sink.table_();
1327 }
1328 }
1329
1330 public void createTaglistSection( ResourceBundle bundle, Sink sink, TagListReportBean report )
1331 {
1332
1333 sink.section1();
1334 sink.sectionTitle2();
1335 sink.anchor( "taglist" );
1336 sink.anchor_();
1337 if ( this.summary )
1338 {
1339 sink.link( "dashboard-report-details.html#taglist" );
1340 sink.text( bundle.getString( "report.taglist.header" ) );
1341 sink.link_();
1342 }
1343 else
1344 {
1345 sink.link( "./taglist.html" );
1346 sink.text( bundle.getString( "report.taglist.header" ) );
1347 sink.link_();
1348 }
1349 sink.sectionTitle2_();
1350 this.linkToTopPage( sink );
1351 sink.lineBreak();
1352 if ( this.isDBAvailable )
1353 {
1354 this.linkToHistoricPage( sink, "taglist" );
1355 }
1356 sink.section1_();
1357
1358 if ( report == null )
1359 {
1360 sink.text( "Error: Unable to read from taglist data file ." );
1361 }
1362 else
1363 {
1364 sink.table();
1365
1366 sink.tableRow();
1367 sink.tableHeaderCell();
1368 sink.text( bundle.getString( "report.taglist.column.tags" ) );
1369 sink.tableHeaderCell_();
1370
1371 sink.tableHeaderCell();
1372 sink.text( bundle.getString( "report.taglist.column.nboccurs" ) );
1373 sink.tableHeaderCell_();
1374
1375 sink.tableRow_();
1376
1377 for ( Iterator ite = report.getTags().entrySet().iterator(); ite.hasNext(); )
1378 {
1379 sink.tableRow();
1380 Map.Entry entry = (Map.Entry) ite.next();
1381 this.sinkCell( sink, (String) entry.getKey() );
1382 this.sinkCell( sink, ( (Integer) entry.getValue() ).toString() );
1383 sink.tableRow_();
1384
1385 }
1386
1387 sink.tableRow();
1388 sink.tableHeaderCell();
1389 sink.text( "Total" );
1390 sink.tableHeaderCell_();
1391
1392 sink.tableHeaderCell();
1393 sink.text( Integer.toString( report.getNbTotal() ) );
1394 sink.tableHeaderCell_();
1395 sink.tableRow_();
1396 sink.tableRow();
1397 sink.tableHeaderCell();
1398 sink.text( bundle.getString( "report.taglist.label.nbclasses" ) );
1399 sink.tableHeaderCell_();
1400
1401 sink.tableHeaderCell();
1402 sink.text( Integer.toString( report.getNbClasses() ) );
1403 sink.tableHeaderCell_();
1404 sink.tableRow_();
1405
1406 sink.table_();
1407
1408 }
1409 sink.lineBreak();
1410 if ( this.generateGraphs )
1411 {
1412 IChartRenderer chart =
1413 new PieChart3DRenderer( new TaglistPieChartStrategy( bundle, this.mavenProject.getProjectName() + " "
1414 + bundle.getString( "chart.taglist.bytags.title" ), report ),
1415 DashBoardReportGenerator.SPECIFIC_WIDTH, ChartUtils.STANDARD_HEIGHT );
1416 if ( !chart.isEmpty() )
1417 {
1418 String filename = this.replaceForbiddenChar( this.mavenProject.getProjectName() );
1419 if ( this.summary )
1420 {
1421 filename += "_Summary_Taglist." + chart.getFileExtension();
1422 }
1423 else
1424 {
1425 filename += "_Taglist." + chart.getFileExtension();
1426 }
1427 filename = filename.replace( ' ', '_' );
1428 String filenameWithPath = this.getImagesPath() + "/" + filename;
1429 this.getLog().debug( "createTaglistGraph = " + filename );
1430 try
1431 {
1432 chart.saveToFile( filenameWithPath );
1433 String link = "images/" + filename;
1434 link = link.replace( ' ', '_' );
1435 sink.figure();
1436 sink.figureGraphics( link );
1437 sink.figure_();
1438 }
1439 catch ( IOException e )
1440 {
1441 this.getLog().debug( "createTaglistGraph exception = " + e.getMessage() );
1442 }
1443 }
1444 }
1445
1446
1447
1448
1449
1450 }
1451 }