Coverage Report - org.apache.maven.plugin.checkstyle.CheckstyleViolationCheckMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
CheckstyleViolationCheckMojo
76%
28/37
50%
18/36
7,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.xml.pull.MXParser;
 26  
 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
 27  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 28  
 
 29  
 import java.io.BufferedReader;
 30  
 import java.io.File;
 31  
 import java.io.FileInputStream;
 32  
 import java.io.IOException;
 33  
 import java.io.InputStreamReader;
 34  
 import java.io.Reader;
 35  
 
 36  
 /**
 37  
  * Perform a violation check against the last Checkstyle run to see if there are
 38  
  * any violations. It reads the Checkstyle output file, counts the number of
 39  
  * violations found and displays it on the console.
 40  
  *
 41  
  * @author <a href="mailto:joakim@erdfelt.net">Joakim Erdfelt</a>
 42  
  * @goal check
 43  
  * @phase verify
 44  
  * @execute goal="checkstyle"
 45  
  * @requiresDependencyResolution compile
 46  
  */
 47  8
 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 lowest severity level that is considered a violation.
 78  
      * Valid values are "error", "warning" and "info".
 79  
      *
 80  
      * @parameter expression="${checkstyle.violationSeverity}" default-value="error"
 81  
      * @since 2.2
 82  
      */
 83  8
     private String violationSeverity = "error";
 84  
 
 85  
     /**
 86  
      * Skip entire check.
 87  
      *
 88  
      * @parameter expression="${checkstyle.skip}" default-value="false"
 89  
      * @since 2.2
 90  
      */
 91  
     private boolean skip;
 92  
 
 93  
     /**
 94  
      * @see org.apache.maven.plugin.Mojo#execute()
 95  
      */
 96  
     public void execute()
 97  
         throws MojoExecutionException, MojoFailureException
 98  
     {
 99  8
         if ( !skip )
 100  
         {
 101  8
             if ( !"xml".equals( outputFileFormat ) )
 102  
             {
 103  2
                 throw new MojoExecutionException( "Output format is '" + outputFileFormat
 104  
                     + "', checkstyle:check requires format to be 'xml'." );
 105  
             }
 106  
 
 107  6
             if ( !outputFile.exists() )
 108  
             {
 109  2
                 getLog().info(
 110  
                                "Unable to perform checkstyle:check, "
 111  
                                    + "unable to find checkstyle:checkstyle outputFile." );
 112  2
                 return;
 113  
             }
 114  
 
 115  
             try
 116  
             {
 117  4
                 XmlPullParser xpp = new MXParser();
 118  
                 // TODO: use ReaderFactory.newXmlReader() when plexus-utils can be upgraded
 119  4
                 Reader freader = new InputStreamReader( new FileInputStream( outputFile ), "UTF-8" );
 120  4
                 BufferedReader breader = new BufferedReader( freader );
 121  4
                 xpp.setInput( breader );
 122  
 
 123  4
                 int violations = countViolations( xpp );
 124  4
                 if ( violations > 0 )
 125  
                 {
 126  4
                     if ( failOnViolation )
 127  
                     {
 128  2
                         throw new MojoFailureException( "You have " + violations + " Checkstyle violation"
 129  
                             + ( ( violations > 1 ) ? "s" : "" ) + "." );
 130  
                     }
 131  
 
 132  2
                     getLog().warn( "checkstyle:check violations detected but failOnViolation set to false" );
 133  
                 }
 134  
             }
 135  0
             catch ( IOException e )
 136  
             {
 137  0
                 throw new MojoExecutionException( "Unable to read Checkstyle results xml: "
 138  
                     + outputFile.getAbsolutePath(), e );
 139  
             }
 140  0
             catch ( XmlPullParserException e )
 141  
             {
 142  0
                 throw new MojoExecutionException( "Unable to read Checkstyle results xml: "
 143  
                     + outputFile.getAbsolutePath(), e );
 144  2
             }
 145  
         }
 146  2
     }
 147  
 
 148  
     private int countViolations( XmlPullParser xpp )
 149  
         throws XmlPullParserException, IOException
 150  
     {
 151  4
         int count = 0;
 152  
 
 153  4
         int eventType = xpp.getEventType();
 154  128
         while ( eventType != XmlPullParser.END_DOCUMENT )
 155  
         {
 156  124
             if ( eventType == XmlPullParser.START_TAG && "error".equals( xpp.getName() )
 157  
                 && isViolation( xpp.getAttributeValue( "", "severity" ) ) )
 158  
             {
 159  20
                 count++;
 160  
             }
 161  124
             eventType = xpp.next();
 162  
         }
 163  
 
 164  4
         return count;
 165  
     }
 166  
 
 167  
     /**
 168  
      * Checks if the given severity is considered a violation.
 169  
      *
 170  
      * @param severity The severity to check
 171  
      * @return <code>true</code> if the given severity is a violation, otherwise <code>false</code>
 172  
      */
 173  
     private boolean isViolation( String severity )
 174  
     {
 175  20
         if ( "error".equals( severity ) )
 176  
         {
 177  20
             return "error".equals( violationSeverity ) || "warning".equals( violationSeverity )
 178  
                 || "info".equals( violationSeverity );
 179  
         }
 180  0
         else if ( "warning".equals( severity ) )
 181  
         {
 182  0
             return "warning".equals( violationSeverity ) || "info".equals( violationSeverity );
 183  
         }
 184  0
         else if ( "info".equals( severity ) )
 185  
         {
 186  0
             return "info".equals( violationSeverity );
 187  
         }
 188  
         else
 189  
         {
 190  0
             return false;
 191  
         }
 192  
     }
 193  
 }