Coverage Report - org.apache.maven.plugin.checkstyle.CheckstyleViolationCheckMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
CheckstyleViolationCheckMojo
65%
36/55
55%
24/44
8,667
 
 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 org.apache.maven.plugin.AbstractMojo;
 23  
 import org.apache.maven.plugin.MojoExecutionException;
 24  
 import org.apache.maven.plugin.MojoFailureException;
 25  
 import org.codehaus.plexus.util.ReaderFactory;
 26  
 import org.codehaus.plexus.util.xml.pull.MXParser;
 27  
 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
 28  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 29  
 
 30  
 import java.io.BufferedReader;
 31  
 import java.io.File;
 32  
 import java.io.IOException;
 33  
 import java.io.Reader;
 34  
 
 35  
 /**
 36  
  * Perform a violation check against the last Checkstyle run to see if there are
 37  
  * any violations. It reads the Checkstyle output file, counts the number of
 38  
  * violations found and displays it on the console.
 39  
  *
 40  
  * @author <a href="mailto:joakim@erdfelt.net">Joakim Erdfelt</a>
 41  
  * @goal check
 42  
  * @phase verify
 43  
  * @execute goal="checkstyle"
 44  
  * @requiresDependencyResolution compile
 45  
  */
 46  4
 public class CheckstyleViolationCheckMojo
 47  
     extends AbstractMojo
 48  
 {
 49  
     /**
 50  
      * Specifies the path and filename to save the Checkstyle output. The format
 51  
      * of the output file is determined by the <code>outputFileFormat</code>
 52  
      * parameter.
 53  
      *
 54  
      * @parameter expression="${checkstyle.output.file}"
 55  
      *            default-value="${project.build.directory}/checkstyle-result.xml"
 56  
      */
 57  
     private File outputFile;
 58  
 
 59  
     /**
 60  
      * Specifies the format of the output to be used when writing to the output
 61  
      * file. Valid values are "plain" and "xml".
 62  
      *
 63  
      * @parameter expression="${checkstyle.output.format}" default-value="xml"
 64  
      */
 65  
     private String outputFileFormat;
 66  
 
 67  
     /**
 68  
      * Do we fail the build on a violation?
 69  
      *
 70  
      * @parameter expression="${checkstyle.failOnViolation}"
 71  
      *            default-value="true"
 72  
      */
 73  
     private boolean failOnViolation;
 74  
 
 75  
     /**
 76  
      * The maximum number of allowed violations. The execution fails only if the
 77  
      * number of violations is above this limit.
 78  
      *
 79  
      * @parameter expression="${checkstyle.maxAllowedViolations}" default-value="0"
 80  
      * @since 2.3
 81  
      */
 82  4
     private int maxAllowedViolations = 0;
 83  
 
 84  
     /**
 85  
      * The lowest severity level that is considered a violation.
 86  
      * Valid values are "error", "warning" and "info".
 87  
      *
 88  
      * @parameter expression="${checkstyle.violationSeverity}" default-value="error"
 89  
      * @since 2.2
 90  
      */
 91  4
     private String violationSeverity = "error";
 92  
 
 93  
     /**
 94  
      * Skip entire check.
 95  
      *
 96  
      * @parameter expression="${checkstyle.skip}" default-value="false"
 97  
      * @since 2.2
 98  
      */
 99  
     private boolean skip;
 100  
 
 101  
     /**
 102  
      * Output the detected violations to the console.
 103  
      *
 104  
      * @parameter expression="${checkstyle.console}" default-value="false"
 105  
      * @since 2.3
 106  
      */
 107  
     private boolean logViolationsToConsole;
 108  
 
 109  
     /**
 110  
      * @see org.apache.maven.plugin.Mojo#execute()
 111  
      */
 112  
     public void execute()
 113  
         throws MojoExecutionException, MojoFailureException
 114  
     {
 115  4
         if ( !skip )
 116  
         {
 117  4
             if ( !"xml".equals( outputFileFormat ) )
 118  
             {
 119  1
                 throw new MojoExecutionException( "Output format is '" + outputFileFormat
 120  
                     + "', checkstyle:check requires format to be 'xml'." );
 121  
             }
 122  
 
 123  3
             if ( !outputFile.exists() )
 124  
             {
 125  1
                 getLog().info(
 126  
                                "Unable to perform checkstyle:check, "
 127  
                                    + "unable to find checkstyle:checkstyle outputFile." );
 128  1
                 return;
 129  
             }
 130  
 
 131  
             try
 132  
             {
 133  2
                 XmlPullParser xpp = new MXParser();
 134  2
                 Reader freader = ReaderFactory.newXmlReader( outputFile );
 135  2
                 BufferedReader breader = new BufferedReader( freader );
 136  2
                 xpp.setInput( breader );
 137  
 
 138  2
                 int violations = countViolations( xpp );
 139  2
                 if ( violations > maxAllowedViolations )
 140  
                 {
 141  2
                     if ( failOnViolation )
 142  
                     {
 143  1
                         String msg = "You have " + violations + " Checkstyle violation"
 144  
                             + ( ( violations > 1 ) ? "s" : "" ) + ".";
 145  1
                         if ( maxAllowedViolations > 0 )
 146  
                         {
 147  0
                             msg += " The maximum number of allowed violations is " + maxAllowedViolations + ".";
 148  
                         }
 149  1
                         throw new MojoFailureException( msg );
 150  
                     }
 151  
 
 152  1
                     getLog().warn( "checkstyle:check violations detected but failOnViolation set to false" );
 153  
                 }
 154  
             }
 155  0
             catch ( IOException e )
 156  
             {
 157  0
                 throw new MojoExecutionException( "Unable to read Checkstyle results xml: "
 158  
                     + outputFile.getAbsolutePath(), e );
 159  
             }
 160  0
             catch ( XmlPullParserException e )
 161  
             {
 162  0
                 throw new MojoExecutionException( "Unable to read Checkstyle results xml: "
 163  
                     + outputFile.getAbsolutePath(), e );
 164  1
             }
 165  
         }
 166  1
     }
 167  
 
 168  
     private int countViolations( XmlPullParser xpp )
 169  
         throws XmlPullParserException, IOException
 170  
     {
 171  2
         int count = 0;
 172  
 
 173  2
         int eventType = xpp.getEventType();
 174  2
         String file = "";
 175  64
         while ( eventType != XmlPullParser.END_DOCUMENT )
 176  
         {
 177  62
             if ( eventType == XmlPullParser.START_TAG && "file".equals( xpp.getName() ) )
 178  
             {
 179  6
                 file = xpp.getAttributeValue( "", "name" );
 180  6
                 file = file.substring( file.lastIndexOf( File.separatorChar ) + 1 );
 181  
             }
 182  
 
 183  62
             if ( eventType == XmlPullParser.START_TAG && "error".equals( xpp.getName() )
 184  
                 && isViolation( xpp.getAttributeValue( "", "severity" ) ) )
 185  
             {
 186  10
                 if ( logViolationsToConsole )
 187  
                 {
 188  0
                     StringBuffer stb = new StringBuffer();
 189  0
                     stb.append( file );
 190  0
                     stb.append( '[' );
 191  0
                     stb.append( xpp.getAttributeValue( "", "line" ) );
 192  0
                     stb.append( ':' );
 193  0
                     stb.append( xpp.getAttributeValue( "", "column" ) );
 194  0
                     stb.append( "] " );
 195  0
                     stb.append( xpp.getAttributeValue( "", "message" ) );
 196  0
                     getLog().error( stb.toString() );
 197  
                 }
 198  10
                 count++;
 199  
             }
 200  62
             eventType = xpp.next();
 201  
         }
 202  
 
 203  2
         return count;
 204  
     }
 205  
 
 206  
     /**
 207  
      * Checks if the given severity is considered a violation.
 208  
      *
 209  
      * @param severity The severity to check
 210  
      * @return <code>true</code> if the given severity is a violation, otherwise <code>false</code>
 211  
      */
 212  
     private boolean isViolation( String severity )
 213  
     {
 214  10
         if ( "error".equals( severity ) )
 215  
         {
 216  10
             return "error".equals( violationSeverity ) || "warning".equals( violationSeverity )
 217  
                 || "info".equals( violationSeverity );
 218  
         }
 219  0
         else if ( "warning".equals( severity ) )
 220  
         {
 221  0
             return "warning".equals( violationSeverity ) || "info".equals( violationSeverity );
 222  
         }
 223  0
         else if ( "info".equals( severity ) )
 224  
         {
 225  0
             return "info".equals( violationSeverity );
 226  
         }
 227  
         else
 228  
         {
 229  0
             return false;
 230  
         }
 231  
     }
 232  
 }