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