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