Coverage Report - org.apache.maven.plugin.checkstyle.CheckstyleReportGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
CheckstyleReportGenerator
85%
357/419
61%
62/102
2,361
 
 1  
 package org.apache.maven.plugin.checkstyle;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import com.puppycrawl.tools.checkstyle.ModuleFactory;
 23  
 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
 24  
 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
 25  
 import com.puppycrawl.tools.checkstyle.api.Configuration;
 26  
 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
 27  
 import org.apache.maven.doxia.tools.SiteTool;
 28  
 import org.apache.maven.plugin.logging.Log;
 29  
 import org.apache.maven.plugin.logging.SystemStreamLog;
 30  
 import org.codehaus.doxia.sink.Sink;
 31  
 import org.codehaus.plexus.util.StringUtils;
 32  
 
 33  
 import java.io.File;
 34  
 import java.util.ArrayList;
 35  
 import java.util.Arrays;
 36  
 import java.util.Collections;
 37  
 import java.util.Iterator;
 38  
 import java.util.List;
 39  
 import java.util.ResourceBundle;
 40  
 
 41  
 /**
 42  
  * Generate a report based on CheckstyleResults.
 43  
  */
 44  
 public class CheckstyleReportGenerator
 45  
 {
 46  
     private Log log;
 47  
 
 48  
     private File basedir;
 49  
 
 50  
     private ResourceBundle bundle;
 51  
 
 52  
     private Sink sink;
 53  
 
 54  
     private SeverityLevel severityLevel;
 55  
 
 56  
     private Configuration checkstyleConfig;
 57  
 
 58  
     private ModuleFactory checkstyleModuleFactory;
 59  
 
 60  
     private boolean enableRulesSummary;
 61  
 
 62  
     private boolean enableSeveritySummary;
 63  
 
 64  
     private boolean enableFilesSummary;
 65  
 
 66  
     private boolean enableRSS;
 67  
 
 68  
     private SiteTool siteTool;
 69  
 
 70  
     private String xrefLocation;
 71  
 
 72  
     public CheckstyleReportGenerator( Sink sink, ResourceBundle bundle, File basedir, SiteTool siteTool )
 73  14
     {
 74  14
         this.bundle = bundle;
 75  
 
 76  14
         this.sink = sink;
 77  
 
 78  14
         this.basedir = basedir;
 79  
 
 80  14
         this.siteTool = siteTool;
 81  
 
 82  14
         this.enableRulesSummary = true;
 83  14
         this.enableSeveritySummary = true;
 84  14
         this.enableFilesSummary = true;
 85  14
         this.enableRSS = true;
 86  14
     }
 87  
 
 88  
     public Log getLog()
 89  
     {
 90  24
         if ( this.log == null )
 91  
         {
 92  0
             this.log = new SystemStreamLog();
 93  
         }
 94  24
         return this.log;
 95  
     }
 96  
 
 97  
     public void setLog( Log log )
 98  
     {
 99  14
         this.log = log;
 100  14
     }
 101  
 
 102  
     private String getTitle()
 103  
     {
 104  
         String title;
 105  
 
 106  28
         if ( getSeverityLevel() == null )
 107  
         {
 108  28
             title = bundle.getString( "report.checkstyle.title" );
 109  
         }
 110  
         else
 111  
         {
 112  0
             title = bundle.getString( "report.checkstyle.severity_title" ) + severityLevel.getName();
 113  
         }
 114  
 
 115  28
         return title;
 116  
     }
 117  
 
 118  
     public void generateReport( CheckstyleResults results )
 119  
     {
 120  14
         doHeading();
 121  
 
 122  14
         if ( getSeverityLevel() == null )
 123  
         {
 124  14
             if ( enableSeveritySummary )
 125  
             {
 126  12
                 doSeveritySummary( results );
 127  
             }
 128  
 
 129  14
             if ( enableFilesSummary )
 130  
             {
 131  12
                 doFilesSummary( results );
 132  
             }
 133  
 
 134  14
             if ( enableRulesSummary )
 135  
             {
 136  12
                 doRulesSummary( results );
 137  
             }
 138  
         }
 139  
 
 140  14
         doDetails( results );
 141  14
         sink.body_();
 142  14
         sink.flush();
 143  14
     }
 144  
 
 145  
     private void doHeading()
 146  
     {
 147  14
         sink.head();
 148  14
         sink.title();
 149  14
         sink.text( getTitle() );
 150  14
         sink.title_();
 151  14
         sink.head_();
 152  
 
 153  14
         sink.body();
 154  
 
 155  14
         sink.section1();
 156  14
         sink.sectionTitle1();
 157  14
         sink.text( getTitle() );
 158  14
         sink.sectionTitle1_();
 159  
 
 160  14
         sink.paragraph();
 161  14
         sink.text( bundle.getString( "report.checkstyle.checkstylelink" ) + " " );
 162  14
         sink.link( "http://checkstyle.sourceforge.net/" );
 163  14
         sink.text( "Checkstyle" );
 164  14
         sink.link_();
 165  14
         sink.text( "." );
 166  
 
 167  14
         if ( enableRSS )
 168  
         {
 169  14
             sink.nonBreakingSpace();
 170  14
             sink.link( "checkstyle.rss" );
 171  14
             sink.figure();
 172  14
             sink.figureCaption();
 173  14
             sink.text( "rss feed" );
 174  14
             sink.figureCaption_();
 175  14
             sink.figureGraphics( "images/rss.png" );
 176  14
             sink.figure_();
 177  14
             sink.link_();
 178  
         }
 179  
 
 180  14
         sink.paragraph_();
 181  14
         sink.section1_();
 182  14
     }
 183  
 
 184  
     private void iconSeverity( String level )
 185  
     {
 186  726
         if ( SeverityLevel.INFO.getName().equalsIgnoreCase( level ) )
 187  
         {
 188  2
             iconInfo();
 189  
         }
 190  724
         else if ( SeverityLevel.WARNING.getName().equalsIgnoreCase( level ) )
 191  
         {
 192  4
             iconWarning();
 193  
         }
 194  720
         else if ( SeverityLevel.ERROR.getName().equalsIgnoreCase( level ) )
 195  
         {
 196  720
             iconError();
 197  
         }
 198  726
     }
 199  
 
 200  
     private void iconInfo()
 201  
     {
 202  26
         sink.figure();
 203  26
         sink.figureCaption();
 204  26
         sink.text( bundle.getString( "report.checkstyle.infos" ) );
 205  26
         sink.figureCaption_();
 206  26
         sink.figureGraphics( "images/icon_info_sml.gif" );
 207  26
         sink.figure_();
 208  26
     }
 209  
 
 210  
     private void iconWarning()
 211  
     {
 212  32
         sink.figure();
 213  32
         sink.figureCaption();
 214  32
         sink.text( bundle.getString( "report.checkstyle.warnings" ) );
 215  32
         sink.figureCaption_();
 216  32
         sink.figureGraphics( "images/icon_warning_sml.gif" );
 217  32
         sink.figure_();
 218  32
     }
 219  
 
 220  
     private void iconError()
 221  
     {
 222  814
         sink.figure();
 223  814
         sink.figureCaption();
 224  814
         sink.text( bundle.getString( "report.checkstyle.errors" ) );
 225  814
         sink.figureCaption_();
 226  814
         sink.figureGraphics( "images/icon_error_sml.gif" );
 227  814
         sink.figure_();
 228  814
     }
 229  
 
 230  
     /**
 231  
      * Get the value of the specified attribute from the Checkstyle configuration.
 232  
      * If parentConfigurations is non-null and non-empty, the parent
 233  
      * configurations are searched if the attribute cannot be found in the
 234  
      * current configuration. If the attribute is still not found, the
 235  
      * specified default value will be returned.
 236  
      *
 237  
      * @param config The current Checkstyle configuration
 238  
      * @param parentConfigurations The configurations for the parents of the current configuration
 239  
      * @param attributeName The name of the attribute
 240  
      * @param defaultValue The default value to use if the attribute cannot be found in any configuration
 241  
      * @return The value of the specified attribute
 242  
      */
 243  
     private String getConfigAttribute( Configuration config, List parentConfigurations, String attributeName,
 244  
                                        String defaultValue )
 245  
     {
 246  
         String ret;
 247  
         try
 248  
         {
 249  3632
             ret = config.getAttribute( attributeName );
 250  
         }
 251  3566
         catch ( CheckstyleException e )
 252  
         {
 253  
             // Try to find the attribute in a parent, if there are any
 254  3566
             if ( parentConfigurations != null && !parentConfigurations.isEmpty() )
 255  
             {
 256  1410
                 Configuration parentConfiguration =
 257  
                     (Configuration) parentConfigurations.get( parentConfigurations.size() - 1 );
 258  1410
                 List newParentConfigurations = new ArrayList( parentConfigurations );
 259  
                 // Remove the last parent
 260  1410
                 newParentConfigurations.remove( parentConfiguration );
 261  1410
                 ret = getConfigAttribute( parentConfiguration, newParentConfigurations, attributeName, defaultValue );
 262  
             }
 263  
             else
 264  
             {
 265  2156
                 ret = defaultValue;
 266  
             }
 267  66
         }
 268  3632
         return ret;
 269  
     }
 270  
 
 271  
     /**
 272  
      * Create the rules summary section of the report.
 273  
      *
 274  
      * @param results The results to summarize
 275  
      */
 276  
     private void doRulesSummary( CheckstyleResults results )
 277  
     {
 278  12
         if ( checkstyleConfig == null )
 279  
         {
 280  0
             return;
 281  
         }
 282  
 
 283  12
         sink.section1();
 284  12
         sink.sectionTitle1();
 285  12
         sink.text( bundle.getString( "report.checkstyle.rules" ) );
 286  12
         sink.sectionTitle1_();
 287  
 
 288  12
         sink.table();
 289  
 
 290  12
         sink.tableRow();
 291  12
         sink.tableHeaderCell();
 292  12
         sink.text( bundle.getString( "report.checkstyle.rules" ) );
 293  12
         sink.tableHeaderCell_();
 294  
 
 295  12
         sink.tableHeaderCell();
 296  12
         sink.text( bundle.getString( "report.checkstyle.violations" ) );
 297  12
         sink.tableHeaderCell_();
 298  
 
 299  12
         sink.tableHeaderCell();
 300  12
         sink.text( bundle.getString( "report.checkstyle.column.severity" ) );
 301  12
         sink.tableHeaderCell_();
 302  12
         sink.tableRow_();
 303  
 
 304  
         // Top level should be the checker.
 305  12
         if ( "checker".equalsIgnoreCase( checkstyleConfig.getName() ) )
 306  
         {
 307  12
             doRuleChildren( checkstyleConfig, null, results );
 308  
         }
 309  
         else
 310  
         {
 311  0
             sink.tableRow();
 312  0
             sink.tableCell();
 313  0
             sink.text( bundle.getString( "report.checkstyle.norule" ) );
 314  0
             sink.tableCell_();
 315  0
             sink.tableRow_();
 316  
         }
 317  
 
 318  12
         sink.table_();
 319  
 
 320  12
         sink.section1_();
 321  12
     }
 322  
 
 323  
     /**
 324  
      * Create a summary for each Checkstyle rule.
 325  
      *
 326  
      * @param configuration The Checkstyle configuration
 327  
      * @param parentConfigurations A List of configurations for the chain of parents to the current configuration
 328  
      * @param results The results to summarize
 329  
      */
 330  
     private void doRuleChildren( Configuration configuration, List parentConfigurations, CheckstyleResults results )
 331  
     {
 332  
         // Remember the chain of parent configurations
 333  24
         if ( parentConfigurations == null )
 334  
         {
 335  12
             parentConfigurations = new ArrayList();
 336  
         }
 337  
         // The "oldest" parent will be first in the list
 338  24
         parentConfigurations.add( configuration );
 339  
 
 340  24
         if ( getLog().isDebugEnabled() )
 341  
         {
 342  
             // Log the parent configuration path
 343  0
             StringBuffer parentPath = new StringBuffer();
 344  0
             Iterator iterator = parentConfigurations.iterator();
 345  0
             while ( iterator.hasNext() )
 346  
             {
 347  0
                 Configuration parentConfiguration = (Configuration) iterator.next();
 348  0
                 parentPath.append( parentConfiguration.getName() );
 349  0
                 if ( iterator.hasNext() )
 350  
                 {
 351  0
                     parentPath.append( " --> " );
 352  
                 }
 353  
             }
 354  0
             if ( parentPath.length() > 0 )
 355  
             {
 356  0
                 getLog().debug( "Parent Configuration Path: " + parentPath.toString() );
 357  
             }
 358  
         }
 359  
 
 360  24
         Configuration configChildren[] = configuration.getChildren();
 361  762
         for ( int cci = 0; cci < configChildren.length; cci++ )
 362  
         {
 363  738
             String ruleName = configChildren[cci].getName();
 364  
 
 365  738
             if ( "TreeWalker".equals( ruleName ) )
 366  
             {
 367  
                 // special sub-case
 368  12
                 doRuleChildren( configChildren[cci], parentConfigurations, results );
 369  
             }
 370  
             else
 371  
             {
 372  726
                 doRuleRow( configChildren[cci], parentConfigurations, ruleName, results );
 373  
             }
 374  
         }
 375  24
     }
 376  
 
 377  
     /**
 378  
      * Create a summary for one Checkstyle rule.
 379  
      *
 380  
      * @param checkerConfig Configuration for the Checkstyle rule
 381  
      * @param parentConfigurations Configurations for the parents of this rule
 382  
      * @param ruleName The name of the rule, for example "JavadocMethod"
 383  
      * @param results The results to summarize
 384  
      */
 385  
     private void doRuleRow( Configuration checkerConfig, List parentConfigurations, String ruleName,
 386  
                             CheckstyleResults results )
 387  
     {
 388  726
         sink.tableRow();
 389  726
         sink.tableCell();
 390  726
         sink.text( ruleName );
 391  
 
 392  726
         List attribnames = new ArrayList( Arrays.asList( checkerConfig.getAttributeNames() ) );
 393  726
         attribnames.remove( "severity" ); // special value (deserves unique column)
 394  726
         if ( !attribnames.isEmpty() )
 395  
         {
 396  30
             sink.list();
 397  30
             Iterator it = attribnames.iterator();
 398  74
             while ( it.hasNext() )
 399  
             {
 400  44
                 sink.listItem();
 401  44
                 String name = (String) it.next();
 402  44
                 sink.bold();
 403  44
                 sink.text( name );
 404  44
                 sink.bold_();
 405  
 
 406  44
                 String value = getConfigAttribute( checkerConfig, null, name, "" );
 407  
                 // special case, Header.header and RegexpHeader.header
 408  44
                 if ( "header".equals( name ) && ( "Header".equals( ruleName ) || "RegexpHeader".equals( ruleName ) ) )
 409  
                 {
 410  0
                     List lines = stringSplit( value, "\\n" );
 411  0
                     int linenum = 1;
 412  0
                     Iterator itl = lines.iterator();
 413  0
                     while ( itl.hasNext() )
 414  
                     {
 415  0
                         String line = (String) itl.next();
 416  0
                         sink.lineBreak();
 417  0
                         sink.rawText( "<span style=\"color: gray\">" );
 418  0
                         sink.text( linenum + ":" );
 419  0
                         sink.rawText( "</span>" );
 420  0
                         sink.nonBreakingSpace();
 421  0
                         sink.monospaced();
 422  0
                         sink.text( line );
 423  0
                         sink.monospaced_();
 424  0
                         linenum++;
 425  
                     }
 426  
                 }
 427  44
                 else if ( "headerFile".equals( name ) && "RegexpHeader".equals( ruleName ) )
 428  
                 {
 429  2
                     sink.text( ": " );
 430  2
                     sink.monospaced();
 431  2
                     sink.text( "\"" );
 432  2
                     if ( basedir != null )
 433  
                     {
 434  
                         // Make the headerFile value relative to ${basedir}
 435  2
                         String path = siteTool.getRelativePath( value, basedir.getAbsolutePath() );
 436  2
                         sink.text( path.replace( '\\', '/' ) );
 437  
                     }
 438  
                     else
 439  
                     {
 440  0
                         sink.text( value );
 441  
                     }
 442  2
                     sink.text( "\"" );
 443  2
                     sink.monospaced_();
 444  
                 }
 445  
                 else
 446  
                 {
 447  42
                     sink.text( ": " );
 448  42
                     sink.monospaced();
 449  42
                     sink.text( "\"" );
 450  42
                     sink.text( value );
 451  42
                     sink.text( "\"" );
 452  42
                     sink.monospaced_();
 453  
                 }
 454  44
                 sink.listItem_();
 455  
             }
 456  30
             sink.list_();
 457  
         }
 458  
 
 459  726
         sink.tableCell_();
 460  
 
 461  726
         sink.tableCell();
 462  726
         String fixedmessage = getConfigAttribute( checkerConfig, null, "message", null );
 463  
         // Grab the severity from the rule configuration, use null as default value
 464  726
         String configSeverity = getConfigAttribute( checkerConfig, null, "severity", null );
 465  726
         sink.text( countRuleViolation( results.getFiles().values().iterator(), ruleName, fixedmessage,
 466  
                                        configSeverity ) );
 467  726
         sink.tableCell_();
 468  
 
 469  726
         sink.tableCell();
 470  
         // Grab the severity from the rule configuration, this time use error as default value
 471  
         // Also pass along all parent configurations, so that we can try to find the severity there
 472  726
         configSeverity = getConfigAttribute( checkerConfig, parentConfigurations, "severity", "error" );
 473  726
         iconSeverity( configSeverity );
 474  726
         sink.nonBreakingSpace();
 475  726
         sink.text( StringUtils.capitalise( configSeverity ) );
 476  726
         sink.tableCell_();
 477  
 
 478  726
         sink.tableRow_();
 479  726
     }
 480  
 
 481  
     /**
 482  
      * Splits a string against a delim consisting of a string (not a single character).
 483  
      *
 484  
      * @param input
 485  
      * @param delim
 486  
      * @return
 487  
      */
 488  
     private List stringSplit( String input, String delim )
 489  
     {
 490  0
         List ret = new ArrayList();
 491  
 
 492  0
         int delimLen = delim.length();
 493  0
         int offset = 0;
 494  0
         int lastOffset = 0;
 495  
         String line;
 496  
 
 497  0
         while ( ( offset = input.indexOf( delim, offset ) ) >= 0 )
 498  
         {
 499  0
             line = input.substring( lastOffset, offset );
 500  0
             ret.add( line );
 501  0
             offset += delimLen;
 502  0
             lastOffset = offset;
 503  
         }
 504  
 
 505  0
         line = input.substring( lastOffset );
 506  0
         ret.add( line );
 507  
 
 508  0
         return ret;
 509  
     }
 510  
 
 511  
     /**
 512  
      * Count the number of violations for the given rule.
 513  
      *
 514  
      * @param files An iterator over the set of files that has violations
 515  
      * @param ruleName The name of the rule
 516  
      * @param message A message that, if it's not null, will be matched to the message from the violation
 517  
      * @param severity A severity that, if it's not null, will be matched to the severity from the violation
 518  
      * @return The number of rule violations
 519  
      */
 520  
     private String countRuleViolation( Iterator files, String ruleName, String message, String severity )
 521  
     {
 522  726
         long count = 0;
 523  
         String sourceName;
 524  
 
 525  
         try
 526  
         {
 527  726
             sourceName = checkstyleModuleFactory.createModule( ruleName ).getClass().getName();
 528  
         }
 529  0
         catch ( CheckstyleException e )
 530  
         {
 531  0
             getLog().error( "Unable to obtain Source Name for Rule '" + ruleName + "'.", e );
 532  0
             return "(report failure)";
 533  726
         }
 534  
 
 535  2082
         while ( files.hasNext() )
 536  
         {
 537  1356
             List errors = (List) files.next();
 538  
 
 539  1356
             for ( Iterator error = errors.iterator(); error.hasNext(); )
 540  
             {
 541  3822
                 AuditEvent event = (AuditEvent) error.next();
 542  
 
 543  3822
                 if ( event.getSourceName().equals( sourceName ) )
 544  
                 {
 545  
                     // check message too, for those that have a specific one.
 546  
                     // like GenericIllegalRegexp and Regexp
 547  64
                     if ( message != null )
 548  
                     {
 549  
                         // event.getMessage() uses java.text.MessageFormat in its implementation.
 550  
                         // Read MessageFormat Javadoc about single quote:
 551  
                         // http://java.sun.com/j2se/1.4.2/docs/api/java/text/MessageFormat.html
 552  0
                         String msgWithoutSingleQuote = StringUtils.replace( message, "'", "" );
 553  0
                         if ( message.equals( event.getMessage() )
 554  
                             || msgWithoutSingleQuote.equals( event.getMessage() ) )
 555  
                         {
 556  0
                             count++;
 557  
                         }
 558  
                     }
 559  
                     // Check the severity. This helps to distinguish between
 560  
                     // different configurations for the same rule, where each
 561  
                     // configuration has a different severity, like JavadocMetod.
 562  
                     // See also http://jira.codehaus.org/browse/MCHECKSTYLE-41
 563  64
                     else if ( severity != null )
 564  
                     {
 565  4
                         if ( severity.equals( event.getSeverityLevel().getName() ) )
 566  
                         {
 567  4
                             count++;
 568  
                         }
 569  
                     }
 570  
                     else
 571  
                     {
 572  60
                         count++;
 573  
                     }
 574  
                 }
 575  
             }
 576  
         }
 577  
 
 578  726
         return String.valueOf( count );
 579  
     }
 580  
 
 581  
     private void doSeveritySummary( CheckstyleResults results )
 582  
     {
 583  12
         sink.section1();
 584  12
         sink.sectionTitle1();
 585  12
         sink.text( bundle.getString( "report.checkstyle.summary" ) );
 586  12
         sink.sectionTitle1_();
 587  
 
 588  12
         sink.table();
 589  
 
 590  12
         sink.tableRow();
 591  12
         sink.tableHeaderCell();
 592  12
         sink.text( bundle.getString( "report.checkstyle.files" ) );
 593  12
         sink.tableHeaderCell_();
 594  
 
 595  12
         sink.tableHeaderCell();
 596  12
         sink.text( bundle.getString( "report.checkstyle.infos" ) );
 597  12
         sink.nonBreakingSpace();
 598  12
         iconInfo();
 599  12
         sink.tableHeaderCell_();
 600  
 
 601  12
         sink.tableHeaderCell();
 602  12
         sink.text( bundle.getString( "report.checkstyle.warnings" ) );
 603  12
         sink.nonBreakingSpace();
 604  12
         iconWarning();
 605  12
         sink.tableHeaderCell_();
 606  
 
 607  12
         sink.tableHeaderCell();
 608  12
         sink.text( bundle.getString( "report.checkstyle.errors" ) );
 609  12
         sink.nonBreakingSpace();
 610  12
         iconError();
 611  12
         sink.tableHeaderCell_();
 612  12
         sink.tableRow_();
 613  
 
 614  12
         sink.tableRow();
 615  12
         sink.tableCell();
 616  12
         sink.text( String.valueOf( results.getFileCount() ) );
 617  12
         sink.tableCell_();
 618  12
         sink.tableCell();
 619  12
         sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.INFO ) ) );
 620  12
         sink.tableCell_();
 621  12
         sink.tableCell();
 622  12
         sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.WARNING ) ) );
 623  12
         sink.tableCell_();
 624  12
         sink.tableCell();
 625  12
         sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.ERROR ) ) );
 626  12
         sink.tableCell_();
 627  12
         sink.tableRow_();
 628  
 
 629  12
         sink.table_();
 630  
 
 631  12
         sink.section1_();
 632  12
     }
 633  
 
 634  
     private void doFilesSummary( CheckstyleResults results )
 635  
     {
 636  12
         sink.section1();
 637  12
         sink.sectionTitle1();
 638  12
         sink.text( bundle.getString( "report.checkstyle.files" ) );
 639  12
         sink.sectionTitle1_();
 640  
 
 641  12
         sink.table();
 642  
 
 643  12
         sink.tableRow();
 644  12
         sink.tableHeaderCell();
 645  12
         sink.text( bundle.getString( "report.checkstyle.files" ) );
 646  12
         sink.tableHeaderCell_();
 647  12
         sink.tableHeaderCell();
 648  12
         sink.text( bundle.getString( "report.checkstyle.infos.abbrev" ) );
 649  12
         sink.nonBreakingSpace();
 650  12
         iconInfo();
 651  12
         sink.tableHeaderCell_();
 652  12
         sink.tableHeaderCell();
 653  12
         sink.text( bundle.getString( "report.checkstyle.warnings.abbrev" ) );
 654  12
         sink.nonBreakingSpace();
 655  12
         iconWarning();
 656  12
         sink.tableHeaderCell_();
 657  12
         sink.tableHeaderCell();
 658  12
         sink.text( bundle.getString( "report.checkstyle.errors.abbrev" ) );
 659  12
         sink.nonBreakingSpace();
 660  12
         iconError();
 661  12
         sink.tableHeaderCell_();
 662  12
         sink.tableRow_();
 663  
 
 664  
         // Sort the files before writing them to the report
 665  12
         ArrayList fileList = new ArrayList( results.getFiles().keySet() );
 666  12
         Collections.sort( fileList );
 667  
 
 668  12
         for ( Iterator files = fileList.iterator(); files.hasNext(); )
 669  
         {
 670  22
             String filename = (String) files.next();
 671  22
             List violations = results.getFileViolations( filename );
 672  22
             if ( violations.isEmpty() )
 673  
             {
 674  
                 // skip files without violations
 675  0
                 continue;
 676  
             }
 677  
 
 678  22
             sink.tableRow();
 679  
 
 680  22
             sink.tableCell();
 681  22
             sink.link( "#" + filename.replace( '/', '.' ) );
 682  22
             sink.text( filename );
 683  22
             sink.link_();
 684  22
             sink.tableCell_();
 685  
 
 686  22
             sink.tableCell();
 687  22
             sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.INFO ) ) );
 688  22
             sink.tableCell_();
 689  
 
 690  22
             sink.tableCell();
 691  22
             sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.WARNING ) ) );
 692  22
             sink.tableCell_();
 693  
 
 694  22
             sink.tableCell();
 695  22
             sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.ERROR ) ) );
 696  22
             sink.tableCell_();
 697  
 
 698  22
             sink.tableRow_();
 699  
         }
 700  
 
 701  12
         sink.table_();
 702  12
         sink.section1_();
 703  12
     }
 704  
 
 705  
     private void doDetails( CheckstyleResults results )
 706  
     {
 707  
 
 708  14
         sink.section1();
 709  14
         sink.sectionTitle1();
 710  14
         sink.text( bundle.getString( "report.checkstyle.details" ) );
 711  14
         sink.sectionTitle1_();
 712  
 
 713  
         // Sort the files before writing their details to the report
 714  14
         ArrayList fileList = new ArrayList( results.getFiles().keySet() );
 715  14
         Collections.sort( fileList );
 716  14
         Iterator files = fileList.iterator();
 717  
 
 718  40
         while ( files.hasNext() )
 719  
         {
 720  26
             String file = (String) files.next();
 721  26
             List violations = results.getFileViolations( file );
 722  
 
 723  26
             if ( violations.isEmpty() )
 724  
             {
 725  
                 // skip files without violations
 726  0
                 continue;
 727  
             }
 728  
 
 729  26
             sink.section2();
 730  26
             sink.sectionTitle2();
 731  26
             sink.anchor( file.replace( '/', '.' ) );
 732  26
             sink.anchor_();
 733  26
             sink.text( file );
 734  26
             sink.sectionTitle2_();
 735  
 
 736  26
             sink.table();
 737  26
             sink.tableRow();
 738  26
             sink.tableHeaderCell();
 739  26
             sink.text( bundle.getString( "report.checkstyle.column.violation" ) );
 740  26
             sink.tableHeaderCell_();
 741  26
             sink.tableHeaderCell();
 742  26
             sink.text( bundle.getString( "report.checkstyle.column.message" ) );
 743  26
             sink.tableHeaderCell_();
 744  26
             sink.tableHeaderCell();
 745  26
             sink.text( bundle.getString( "report.checkstyle.column.line" ) );
 746  26
             sink.tableHeaderCell_();
 747  26
             sink.tableRow_();
 748  
 
 749  26
             doFileEvents( violations, file );
 750  
 
 751  26
             sink.table_();
 752  26
             sink.section2_();
 753  
         }
 754  
 
 755  14
         sink.section1_();
 756  14
     }
 757  
 
 758  
     private void doFileEvents( List eventList, String filename )
 759  
     {
 760  26
         Iterator events = eventList.iterator();
 761  100
         while ( events.hasNext() )
 762  
         {
 763  74
             AuditEvent event = (AuditEvent) events.next();
 764  74
             SeverityLevel level = event.getSeverityLevel();
 765  
 
 766  74
             if ( ( getSeverityLevel() != null ) && !getSeverityLevel().equals( level ) )
 767  
             {
 768  0
                 continue;
 769  
             }
 770  
 
 771  74
             sink.tableRow();
 772  
 
 773  74
             sink.tableCell();
 774  
 
 775  74
             if ( SeverityLevel.INFO.equals( level ) )
 776  
             {
 777  0
                 iconInfo();
 778  
             }
 779  74
             else if ( SeverityLevel.WARNING.equals( level ) )
 780  
             {
 781  4
                 iconWarning();
 782  
             }
 783  70
             else if ( SeverityLevel.ERROR.equals( level ) )
 784  
             {
 785  70
                 iconError();
 786  
             }
 787  
 
 788  74
             sink.tableCell_();
 789  
 
 790  74
             sink.tableCell();
 791  74
             sink.text( event.getMessage() );
 792  74
             sink.tableCell_();
 793  
 
 794  74
             sink.tableCell();
 795  74
             if ( getXrefLocation() != null )
 796  
             {
 797  74
                 sink
 798  
                     .link(
 799  
                         getXrefLocation() + "/" + filename.replaceAll( "\\.java$", ".html" ) + "#" + event.getLine() );
 800  
             }
 801  74
             sink.text( String.valueOf( event.getLine() ) );
 802  74
             if ( getXrefLocation() != null )
 803  
             {
 804  74
                 sink.link_();
 805  
             }
 806  74
             sink.tableCell_();
 807  
 
 808  74
             sink.tableRow_();
 809  
         }
 810  26
     }
 811  
 
 812  
     public SeverityLevel getSeverityLevel()
 813  
     {
 814  116
         return severityLevel;
 815  
     }
 816  
 
 817  
     public void setSeverityLevel( SeverityLevel severityLevel )
 818  
     {
 819  0
         this.severityLevel = severityLevel;
 820  0
     }
 821  
 
 822  
     public boolean isEnableRulesSummary()
 823  
     {
 824  0
         return enableRulesSummary;
 825  
     }
 826  
 
 827  
     public void setEnableRulesSummary( boolean enableRulesSummary )
 828  
     {
 829  14
         this.enableRulesSummary = enableRulesSummary;
 830  14
     }
 831  
 
 832  
     public boolean isEnableSeveritySummary()
 833  
     {
 834  0
         return enableSeveritySummary;
 835  
     }
 836  
 
 837  
     public void setEnableSeveritySummary( boolean enableSeveritySummary )
 838  
     {
 839  14
         this.enableSeveritySummary = enableSeveritySummary;
 840  14
     }
 841  
 
 842  
     public boolean isEnableFilesSummary()
 843  
     {
 844  0
         return enableFilesSummary;
 845  
     }
 846  
 
 847  
     public void setEnableFilesSummary( boolean enableFilesSummary )
 848  
     {
 849  14
         this.enableFilesSummary = enableFilesSummary;
 850  14
     }
 851  
 
 852  
     public boolean isEnableRSS()
 853  
     {
 854  0
         return enableRSS;
 855  
     }
 856  
 
 857  
     public void setEnableRSS( boolean enableRSS )
 858  
     {
 859  14
         this.enableRSS = enableRSS;
 860  14
     }
 861  
 
 862  
     public String getXrefLocation()
 863  
     {
 864  236
         return xrefLocation;
 865  
     }
 866  
 
 867  
     public void setXrefLocation( String xrefLocation )
 868  
     {
 869  14
         this.xrefLocation = xrefLocation;
 870  14
     }
 871  
 
 872  
     public Configuration getCheckstyleConfig()
 873  
     {
 874  0
         return checkstyleConfig;
 875  
     }
 876  
 
 877  
     public void setCheckstyleConfig( Configuration config )
 878  
     {
 879  14
         this.checkstyleConfig = config;
 880  14
     }
 881  
 
 882  
     public ModuleFactory getCheckstyleModuleFactory()
 883  
     {
 884  0
         return checkstyleModuleFactory;
 885  
     }
 886  
 
 887  
     public void setCheckstyleModuleFactory( ModuleFactory checkstyleModuleFactory )
 888  
     {
 889  14
         this.checkstyleModuleFactory = checkstyleModuleFactory;
 890  14
     }
 891  
 }