Coverage Report - org.apache.maven.plugin.pmd.AbstractPmdReport
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractPmdReport
74%
72/97
55%
43/78
5,5
 
 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.util.ArrayList;
 25  
 import java.util.Collections;
 26  
 import java.util.Iterator;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 import java.util.TreeMap;
 30  
 
 31  
 import org.apache.maven.model.ReportPlugin;
 32  
 import org.apache.maven.project.MavenProject;
 33  
 import org.apache.maven.reporting.AbstractMavenReport;
 34  
 import org.codehaus.doxia.site.renderer.SiteRenderer;
 35  
 import org.codehaus.plexus.util.FileUtils;
 36  
 import org.codehaus.plexus.util.PathTool;
 37  
 import org.codehaus.plexus.util.StringUtils;
 38  
 
 39  
 /**
 40  
  * Base class for the PMD reports.
 41  
  *
 42  
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 43  
  */
 44  12
 public abstract class AbstractPmdReport
 45  
     extends AbstractMavenReport
 46  
 {
 47  
     /**
 48  
      * The output directory for the intermediate XML report.
 49  
      *
 50  
      * @parameter expression="${project.build.directory}"
 51  
      * @required
 52  
      */
 53  
     protected File targetDirectory;
 54  
 
 55  
     /**
 56  
      * The output directory for the final HTML report.
 57  
      *
 58  
      * @parameter expression="${project.reporting.outputDirectory}"
 59  
      * @required
 60  
      */
 61  
     protected String outputDirectory;
 62  
 
 63  
     /**
 64  
      * Site rendering component for generating the HTML report.
 65  
      *
 66  
      * @component
 67  
      */
 68  
     private SiteRenderer siteRenderer;
 69  
 
 70  
     /**
 71  
      * The project to analyse.
 72  
      *
 73  
      * @parameter expression="${project}"
 74  
      * @required
 75  
      * @readonly
 76  
      */
 77  
     protected MavenProject project;
 78  
 
 79  
     /**
 80  
      * Set the output format type, in addition to the HTML report.  Must be one of: "none",
 81  
      * "csv", "xml", "txt" or the full class name of the PMD renderer to use.
 82  
      * See the net.sourceforge.pmd.renderers package javadoc for available renderers.
 83  
      * XML is required if the pmd:check goal is being used.
 84  
      *
 85  
      * @parameter expression="${format}" default-value="xml"
 86  
      */
 87  12
     protected String format = "xml";
 88  
 
 89  
     /**
 90  
      * Link the violation line numbers to the source xref. Links will be created
 91  
      * automatically if the jxr plugin is being used.
 92  
      *
 93  
      * @parameter expression="${linkXRef}" default-value="true"
 94  
      */
 95  
     private boolean linkXRef;
 96  
 
 97  
     /**
 98  
      * Location of the Xrefs to link to.
 99  
      *
 100  
      * @parameter default-value="${project.reporting.outputDirectory}/xref"
 101  
      */
 102  
     private File xrefLocation;
 103  
     
 104  
     /**
 105  
      * Location of the Test Xrefs to link to.
 106  
      *
 107  
      * @parameter default-value="${project.reporting.outputDirectory}/xref-test"
 108  
      */
 109  
     private File xrefTestLocation;
 110  
 
 111  
     /**
 112  
      * A list of files to exclude from checking. Can contain ant-style wildcards and double wildcards.
 113  
      *
 114  
      * @parameter
 115  
      * @since 2.2
 116  
      */
 117  
     private String[] excludes;
 118  
     
 119  
     /**
 120  
      * A list of files to include from checking. Can contain ant-style wildcards and double wildcards.  
 121  
      * Defaults to **\/*.java.
 122  
      *
 123  
      * @parameter
 124  
      * @since 2.2
 125  
      */
 126  
     private String[] includes;
 127  
 
 128  
     
 129  
     
 130  
     
 131  
     /**
 132  
      * The directories containing the sources to be compiled.
 133  
      *
 134  
      * @parameter expression="${project.compileSourceRoots}"
 135  
      * @required
 136  
      * @readonly
 137  
      */
 138  
     private List compileSourceRoots;
 139  
     
 140  
     /**
 141  
      * The directories containing the test-sources to be compiled.
 142  
      *
 143  
      * @parameter expression="${project.testCompileSourceRoots}"
 144  
      * @required
 145  
      * @readonly
 146  
      */
 147  
     private List testSourceRoots;
 148  
     
 149  
     /**
 150  
      * The project source directories that should be excluded.
 151  
      *
 152  
      * @parameter
 153  
      * @since 2.2
 154  
      */
 155  
     private List excludeRoots;
 156  
     
 157  
     /**
 158  
      * Run PMD on the tests.
 159  
      *
 160  
      * @parameter default-value="false"
 161  
      * @since 2.2
 162  
      */
 163  
     protected boolean includeTests;
 164  
     
 165  
     /**
 166  
      * Whether to build an aggregated report at the root, or build individual reports.
 167  
      *
 168  
      * @parameter expression="${aggregate}" default-value="false"
 169  
      * @since 2.2
 170  
      */
 171  
     protected boolean aggregate;
 172  
         
 173  
     
 174  
     /**
 175  
      * The projects in the reactor for aggregation report.
 176  
      *
 177  
      * @parameter expression="${reactorProjects}"
 178  
      * @readonly
 179  
      */
 180  
     protected List reactorProjects;
 181  
 
 182  
     /**
 183  
      * @see org.apache.maven.reporting.AbstractMavenReport#getProject()
 184  
      */
 185  
     protected MavenProject getProject()
 186  
     {
 187  44
         return project;
 188  
     }
 189  
 
 190  
     /**
 191  
      * @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer()
 192  
      */
 193  
     protected SiteRenderer getSiteRenderer()
 194  
     {
 195  19
         return siteRenderer;
 196  
     }
 197  
 
 198  
     protected String constructXRefLocation( boolean test )
 199  
     {
 200  11
         String location = null;
 201  11
         if ( linkXRef )
 202  
         {
 203  5
             File xrefLoc = test ? xrefTestLocation : xrefLocation;
 204  
             
 205  5
             String relativePath = PathTool.getRelativePath( outputDirectory, xrefLoc.getAbsolutePath() );
 206  5
             if ( StringUtils.isEmpty( relativePath ) )
 207  
             {
 208  5
                 relativePath = ".";
 209  
             }
 210  5
             relativePath = relativePath + "/" + xrefLoc.getName();
 211  5
             if ( xrefLoc.exists() )
 212  
             {
 213  
                 // XRef was already generated by manual execution of a lifecycle binding
 214  2
                 location = relativePath;
 215  
             }
 216  
             else
 217  
             {
 218  
                 // Not yet generated - check if the report is on its way
 219  3
                 for ( Iterator reports = project.getReportPlugins().iterator(); reports.hasNext(); )
 220  
                 {
 221  3
                     ReportPlugin plugin = (ReportPlugin) reports.next();
 222  
 
 223  3
                     String artifactId = plugin.getArtifactId();
 224  3
                     if ( "maven-jxr-plugin".equals( artifactId ) || "jxr-maven-plugin".equals( artifactId ) )
 225  
                     {
 226  3
                         location = relativePath;
 227  
                     }
 228  
                 }
 229  
             }
 230  
 
 231  5
             if ( location == null )
 232  
             {
 233  0
                 getLog().warn( "Unable to locate Source XRef to link to - DISABLED" );
 234  
             }
 235  
         }
 236  11
         return location;
 237  
     }
 238  
 
 239  
     /**
 240  
      * Convenience method to get the list of files where the PMD tool will be executed
 241  
      *
 242  
      * @return a List of the files where the PMD tool will be executed
 243  
      * @throws java.io.IOException
 244  
      */
 245  
     protected Map getFilesToProcess( )
 246  
         throws IOException
 247  
     {
 248  11
         String sourceXref = constructXRefLocation( false );
 249  11
         String testXref = includeTests ? constructXRefLocation( true ) : "";
 250  
         
 251  11
         if ( aggregate && !project.isExecutionRoot() )
 252  
         {
 253  0
             return Collections.EMPTY_MAP;
 254  
         }
 255  
 
 256  11
         if ( excludeRoots == null )
 257  
         {
 258  9
             excludeRoots = Collections.EMPTY_LIST;
 259  
         }
 260  11
         List excludeRootFiles = new ArrayList( excludeRoots.size() );
 261  
         
 262  11
         for ( Iterator it = excludeRoots.iterator(); it.hasNext(); ) 
 263  
         {
 264  0
             String root = (String) it.next();
 265  0
             File file = new File( root );
 266  0
             if ( file.exists()
 267  
                 && file.isDirectory() )
 268  
             {
 269  0
                 excludeRootFiles.add( file );
 270  
             }
 271  
         }
 272  
         
 273  11
         List directories = new ArrayList();
 274  
         
 275  11
         for ( Iterator i = compileSourceRoots.iterator(); i.hasNext(); )
 276  
         {
 277  9
             String root = (String) i.next();
 278  9
             File sroot = new File( root );
 279  9
             directories.add( new PmdFileInfo( project, sroot, sourceXref ) );
 280  
         }
 281  
         
 282  9
         if ( includeTests )
 283  
         {
 284  0
             for ( Iterator i = testSourceRoots.iterator(); i.hasNext(); )
 285  
             {
 286  0
                 String root = (String) i.next();
 287  0
                 File sroot = new File( root );
 288  0
                 directories.add( new PmdFileInfo( project, sroot, testXref ) );
 289  
             }
 290  
         }
 291  9
         if ( aggregate )
 292  
         {
 293  0
             for ( Iterator i = reactorProjects.iterator(); i.hasNext(); )
 294  
             {
 295  0
                 MavenProject localProject = (MavenProject) i.next();
 296  0
                 for ( Iterator i2 = localProject.getCompileSourceRoots().iterator(); i2.hasNext(); )
 297  
                 {
 298  0
                     String root = (String) i2.next();
 299  0
                     File sroot = new File( root );
 300  0
                     directories.add( new PmdFileInfo( localProject, sroot, sourceXref ) );
 301  
                 }
 302  0
                 if ( includeTests )
 303  
                 {
 304  0
                     for ( Iterator i2 = localProject.getTestCompileSourceRoots().iterator(); i2.hasNext(); )
 305  
                     {
 306  0
                         String root = (String) i2.next();
 307  0
                         File sroot = new File( root );
 308  0
                         directories.add( new PmdFileInfo( localProject, sroot, testXref ) );
 309  
                     }
 310  
                 }
 311  
             }
 312  
   
 313  
         }
 314  
         
 315  9
         String excluding = getIncludeExcludeString( excludes );
 316  9
         String including = getIncludeExcludeString( includes );
 317  9
         Map files = new TreeMap();
 318  
         
 319  9
         if ( "".equals( including ) )
 320  
         {
 321  9
             including = "**/*.java";
 322  
         }
 323  
 
 324  9
         StringBuffer excludesStr = new StringBuffer();
 325  9
         if ( StringUtils.isNotEmpty( excluding ) )
 326  
         {
 327  4
             excludesStr.append( excluding );
 328  
         }
 329  9
         String[] defaultExcludes = FileUtils.getDefaultExcludes();
 330  180
         for ( int i = 0; i < defaultExcludes.length; i++ )
 331  
         {
 332  171
             if ( excludesStr.length() > 0 )
 333  
             {
 334  166
                 excludesStr.append( "," );
 335  
             }
 336  171
             excludesStr.append( defaultExcludes[i] );
 337  
         }
 338  9
         getLog().debug( "Excluded files: '" + excludesStr + "'" );
 339  
 
 340  9
         for ( Iterator it = directories.iterator(); it.hasNext(); )
 341  
         {
 342  9
             PmdFileInfo finfo = (PmdFileInfo) it.next();
 343  9
             File sourceDirectory = finfo.getSourceDirectory();
 344  9
             if ( sourceDirectory.exists()
 345  
                 && sourceDirectory.isDirectory()
 346  
                 && !excludeRootFiles.contains( sourceDirectory ) )
 347  
             {
 348  9
                 List newfiles = FileUtils.getFiles( sourceDirectory, including, excludesStr.toString() );
 349  9
                 for ( Iterator it2 = newfiles.iterator(); it2.hasNext(); )
 350  
                 {
 351  25
                     files.put( it2.next(), finfo );
 352  
                 }
 353  
             }
 354  
         }        
 355  
                 
 356  9
         return files;
 357  
     }
 358  
 
 359  
     /**
 360  
      * Convenience method that concatenates the files to be excluded into the appropriate format.
 361  
      *
 362  
      * @param arr the array of Strings that contains the files to be excluded
 363  
      * @return a String that contains the concatenated file names
 364  
      */
 365  
     private String getIncludeExcludeString( String[] arr )
 366  
     {
 367  18
         StringBuffer str = new StringBuffer();
 368  
 
 369  18
         if ( arr != null )
 370  
         {
 371  10
             for ( int index = 0; index < arr.length; index++ )
 372  
             {
 373  6
                 if ( str.length() > 0 )
 374  
                 {
 375  2
                     str.append( ',' );
 376  
                 }
 377  6
                 str.append( arr[index] );
 378  
             }
 379  
         }
 380  
 
 381  18
         return str.toString();
 382  
     }
 383  
 
 384  
 
 385  
     protected boolean isHtml()
 386  
     {
 387  7
         return "html".equals( format );
 388  
     }
 389  
 
 390  
     /**
 391  
      * @see org.apache.maven.reporting.AbstractMavenReport#canGenerateReport()
 392  
      */
 393  
     public boolean canGenerateReport()
 394  
     {
 395  10
         if ( aggregate && !project.isExecutionRoot() )
 396  
         {
 397  0
             return false;
 398  
         }
 399  
 
 400  
         // if format is XML, we need to output it even if the file list is empty
 401  
         // so the "check" goals can check for failures
 402  10
         if ( "xml".equals( format ) )
 403  
         {
 404  6
             return true;
 405  
         }
 406  
         try 
 407  
         {
 408  4
             Map filesToProcess = getFilesToProcess( );
 409  2
             if ( filesToProcess.isEmpty() )
 410  
             {
 411  0
                 return false;
 412  
             }
 413  
         }
 414  0
         catch ( IOException e )
 415  
         {
 416  0
             getLog().error( e );
 417  2
         }
 418  2
         return true;
 419  
     }
 420  
 
 421  
     /**
 422  
      * @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory()
 423  
      */
 424  
     protected String getOutputDirectory()
 425  
     {
 426  11
         return outputDirectory;
 427  
     }
 428  
 }