Coverage Report - org.apache.maven.plugin.pmd.AbstractPmdViolationCheckMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractPmdViolationCheckMojo
89%
50/56
78%
30/38
4,25
 
 1  
 package org.apache.maven.plugin.pmd;
 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.io.IOException;
 24  
 import java.io.Reader;
 25  
 import java.util.ArrayList;
 26  
 import java.util.List;
 27  
 
 28  
 import org.apache.maven.plugin.AbstractMojo;
 29  
 import org.apache.maven.plugin.MojoExecutionException;
 30  
 import org.apache.maven.plugin.MojoFailureException;
 31  
 import org.apache.maven.project.MavenProject;
 32  
 import org.codehaus.plexus.util.IOUtil;
 33  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 34  
 
 35  
 /**
 36  
  * Base class for mojos that check if there were any PMD violations.
 37  
  *
 38  
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 39  
  * @version $Id: org.apache.maven.plugin.pmd.AbstractPmdViolationCheckMojo.html 816698 2012-05-08 15:21:08Z hboutemy $
 40  
  */
 41  8
 public abstract class AbstractPmdViolationCheckMojo<D>
 42  
     extends AbstractMojo
 43  
 {
 44  
     /**
 45  
      * The location of the XML report to check, as generated by the PMD report.
 46  
      *
 47  
      * @parameter expression="${project.build.directory}"
 48  
      * @required
 49  
      */
 50  
     private File targetDirectory;
 51  
 
 52  
     /**
 53  
      * Whether to fail the build if the validation check fails.
 54  
      *
 55  
      * @parameter expression="${pmd.failOnViolation}" default-value="true"
 56  
      * @required
 57  
      */
 58  
     private boolean failOnViolation;
 59  
 
 60  
     /**
 61  
      * The project language, for determining whether to run the report.
 62  
      *
 63  
      * @parameter expression="${project.artifact.artifactHandler.language}"
 64  
      * @required
 65  
      * @readonly
 66  
      */
 67  
     private String language;
 68  
 
 69  
     /**
 70  
      * Whether to build an aggregated report at the root, or build individual reports.
 71  
      *
 72  
      * @parameter expression="${aggregate}" default-value="false"
 73  
      * @since 2.2
 74  
      */
 75  
     protected boolean aggregate;
 76  
 
 77  
     /**
 78  
      * Print details of check failures to build output.
 79  
      *
 80  
      * @parameter expression="${pmd.verbose}" default-value="false"
 81  
      */
 82  
     private boolean verbose;
 83  
 
 84  
     /**
 85  
      * The project to analyze.
 86  
      *
 87  
      * @parameter expression="${project}"
 88  
      * @required
 89  
      * @readonly
 90  
      */
 91  
     protected MavenProject project;
 92  
 
 93  
     protected void executeCheck( String filename, String tagName, String key, int failurePriority )
 94  
         throws MojoFailureException, MojoExecutionException
 95  
     {
 96  4
         if ( aggregate && !project.isExecutionRoot() )
 97  
         {
 98  0
             return;
 99  
         }
 100  
 
 101  4
         if ( "java".equals( language ) || aggregate )
 102  
         {
 103  4
             File outputFile = new File( targetDirectory, filename );
 104  
 
 105  4
             if ( outputFile.exists() )
 106  
             {
 107  4
                 Reader reader = null;
 108  
                 try
 109  
                 {
 110  4
                     ViolationDetails<D> violations = getViolations( outputFile, failurePriority );
 111  
 
 112  4
                     List<D> failures = violations.getFailureDetails();
 113  4
                     List<D> warnings = violations.getWarningDetails();
 114  
 
 115  4
                     if ( verbose )
 116  
                     {
 117  1
                         printErrors( failures, warnings );
 118  
                     }
 119  
 
 120  4
                     int failureCount = failures.size();
 121  4
                     int warningCount = warnings.size();
 122  
 
 123  4
                     String message = getMessage( failureCount, warningCount, key, outputFile );
 124  
 
 125  4
                     if ( failureCount > 0 && failOnViolation )
 126  
                     {
 127  1
                         throw new MojoFailureException( message );
 128  
                     }
 129  
 
 130  3
                     this.getLog().info( message );
 131  
                 }
 132  0
                 catch ( IOException e )
 133  
                 {
 134  0
                     throw new MojoExecutionException(
 135  
                                                       "Unable to read PMD results xml: " + outputFile.getAbsolutePath(),
 136  
                                                       e );
 137  
                 }
 138  0
                 catch ( XmlPullParserException e )
 139  
                 {
 140  0
                     throw new MojoExecutionException(
 141  
                                                       "Unable to read PMD results xml: " + outputFile.getAbsolutePath(),
 142  
                                                       e );
 143  
                 }
 144  
                 finally
 145  
                 {
 146  4
                     IOUtil.close( reader );
 147  3
                 }
 148  3
             }
 149  
             else
 150  
             {
 151  0
                 throw new MojoFailureException( "Unable to perform check, " + "unable to find " + outputFile );
 152  
             }
 153  
         }
 154  3
     }
 155  
 
 156  
     /**
 157  
      * Method for collecting the violations found by the PMD tool
 158  
      *
 159  
      * @param xpp
 160  
      *            the xml parser object
 161  
      * @param tagName
 162  
      *            the element that will be checked
 163  
      * @return an int that specifies the number of violations found
 164  
      * @throws XmlPullParserException
 165  
      * @throws IOException
 166  
      */
 167  
     private ViolationDetails<D> getViolations( File analysisFile, int failurePriority )
 168  
         throws XmlPullParserException, IOException
 169  
     {
 170  4
         List<D> failures = new ArrayList<D>();
 171  4
         List<D> warnings = new ArrayList<D>();
 172  
 
 173  4
         List<D> violations = getErrorDetails( analysisFile );
 174  
         
 175  4
         for( D violation : violations )
 176  
         {
 177  19
             int priority = getPriority( violation );
 178  19
             if ( priority <= failurePriority )
 179  
             {
 180  6
                 failures.add( violation );
 181  
             }
 182  
             else
 183  
             {
 184  13
                 warnings.add( violation );
 185  
             }
 186  19
         }
 187  
         
 188  4
         ViolationDetails<D> details = newViolationDetailsInstance();
 189  4
         details.setFailureDetails( failures );
 190  4
         details.setWarningDetails( warnings );
 191  4
         return details;
 192  
     }
 193  
     
 194  
     protected abstract int getPriority( D errorDetail );
 195  
     
 196  
     protected abstract ViolationDetails<D> newViolationDetailsInstance();
 197  
 
 198  
     /**
 199  
      * Prints the warnings and failures
 200  
      *
 201  
      * @param failures
 202  
      *            list of failures
 203  
      * @param warnings
 204  
      *            list of warnings
 205  
      */
 206  
     protected void printErrors( List<D> failures, List<D> warnings )
 207  
     {
 208  1
         for ( D warning :  warnings )
 209  
         {
 210  1
             printError( warning, "Warning" );
 211  
         }
 212  
 
 213  1
         for ( D failure : failures )
 214  
         {
 215  5
             printError( failure, "Failure" );
 216  
         }
 217  1
     }
 218  
 
 219  
     /**
 220  
      * Gets the output message
 221  
      *
 222  
      * @param failureCount
 223  
      * @param warningCount
 224  
      * @param key
 225  
      * @param outputFile
 226  
      * @return
 227  
      */
 228  
     private String getMessage( int failureCount, int warningCount, String key, File outputFile )
 229  
     {
 230  4
         StringBuffer message = new StringBuffer();
 231  4
         if ( failureCount > 0 || warningCount > 0 )
 232  
         {
 233  4
             if ( failureCount > 0 )
 234  
             {
 235  2
                 message.append( "You have " + failureCount + " " + key + ( failureCount > 1 ? "s" : "" ) );
 236  
             }
 237  
 
 238  4
             if ( warningCount > 0 )
 239  
             {
 240  3
                 if ( failureCount > 0 )
 241  
                 {
 242  1
                     message.append( " and " );
 243  
                 }
 244  
                 else
 245  
                 {
 246  2
                     message.append( "You have " );
 247  
                 }
 248  3
                 message.append( warningCount + " warning" + ( warningCount > 1 ? "s" : "" ) );
 249  
             }
 250  
 
 251  4
             message.append( ". For more details see:" ).append( outputFile.getAbsolutePath() );
 252  
         }
 253  4
         return message.toString();
 254  
     }
 255  
 
 256  
     /**
 257  
      * Formats the failure details and prints them as an INFO message
 258  
      *
 259  
      * @param item
 260  
      */
 261  
     protected abstract void printError( D item, String severity );
 262  
 
 263  
     /**
 264  
      * Gets the attributes and text for the violation tag and puts them in a
 265  
      * HashMap
 266  
      *
 267  
      * @param xpp
 268  
      * @throws XmlPullParserException
 269  
      * @throws IOException
 270  
      */
 271  
     protected abstract List<D> getErrorDetails( File analisysFile )
 272  
         throws XmlPullParserException, IOException;
 273  
 }