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.plugins.annotations.Mojo; 23 import org.apache.maven.plugins.annotations.Parameter; 24 import org.apache.maven.plugins.annotations.ResolutionScope; 25 import org.apache.maven.project.MavenProject; 26 import org.apache.maven.reporting.MavenReportException; 27 import org.codehaus.plexus.util.StringUtils; 28 29 import java.io.File; 30 import java.net.URL; 31 import java.util.Collections; 32 import java.util.HashMap; 33 import java.util.Locale; 34 import java.util.Map; 35 36 /** 37 * A reporting task that performs Checkstyle analysis and generates an HTML report on any violations that Checkstyle finds. 38 * 39 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a> 40 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a> 41 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a> 42 * @version $Id: CheckstyleReport.java 1540563 2013-11-10 22:07:54Z bimargulies $ 43 */ 44 @Mojo( name = "checkstyle", requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true ) 45 public class CheckstyleReport 46 extends AbstractCheckstyleReport 47 { 48 /** 49 * @deprecated Remove with format parameter. 50 */ 51 private static final Map<String, String> FORMAT_TO_CONFIG_LOCATION; 52 53 static 54 { 55 Map<String, String> fmt2Cfg = new HashMap<String, String>(); 56 57 fmt2Cfg.put( "sun", "config/sun_checks.xml" ); 58 fmt2Cfg.put( "turbine", "config/turbine_checks.xml" ); 59 fmt2Cfg.put( "avalon", "config/avalon_checks.xml" ); 60 fmt2Cfg.put( "maven", "config/maven_checks.xml" ); 61 62 FORMAT_TO_CONFIG_LOCATION = Collections.unmodifiableMap( fmt2Cfg ); 63 } 64 65 /** 66 * Specifies the names filter of the source files to be used for Checkstyle. 67 * 68 * <strong>Note:</strong> default value is {@code **\/*.java}. 69 */ 70 @Parameter( property = "checkstyle.includes", defaultValue = JAVA_FILES, required = true ) 71 private String includes; 72 73 /** 74 * Specifies the names filter of the source files to be excluded for 75 * Checkstyle. 76 */ 77 @Parameter( property = "checkstyle.excludes" ) 78 private String excludes; 79 80 /** 81 * Specifies the names filter of the source files to be used for Checkstyle. 82 * @since 2.11 83 * 84 * <strong>Note:</strong> default value is {@code **\/*.properties}. 85 */ 86 @Parameter( property = "checkstyle.resourceIncludes", defaultValue = "**/*.properties", required = true ) 87 private String resourceIncludes; 88 89 /** 90 * Specifies the names filter of the source files to be excluded for 91 * Checkstyle. 92 * @since 2.11 93 */ 94 @Parameter( property = "checkstyle.resourceExcludes" ) 95 private String resourceExcludes; 96 97 /** 98 * Specifies whether to include the resource directories in the check. 99 * @since 2.11 100 */ 101 @Parameter( property = "checkstyle.includeResources", defaultValue = "true", required = true ) 102 private boolean includeResources; 103 104 /** 105 * Specifies whether to include the test resource directories in the check. 106 * @since 2.11 107 */ 108 @Parameter( property = "checkstyle.includeTestResources", defaultValue = "true", required = true ) 109 private boolean includeTestResources; 110 111 /** 112 * <p> 113 * Specifies the location of the XML configuration to use. 114 * </p> 115 * <p/> 116 * <p> 117 * Potential values are a filesystem path, a URL, or a classpath resource. 118 * This parameter expects that the contents of the location conform to the 119 * xml format (Checkstyle <a 120 * href="http://checkstyle.sourceforge.net/config.html#Modules">Checker 121 * module</a>) configuration of rulesets. 122 * </p> 123 * <p/> 124 * <p> 125 * This parameter is resolved as resource, URL, then file. If successfully 126 * resolved, the contents of the configuration is copied into the 127 * <code>${project.build.directory}/checkstyle-configuration.xml</code> 128 * file before being passed to Checkstyle as a configuration. 129 * </p> 130 * <p/> 131 * <p> 132 * There are 4 predefined rulesets. 133 * </p> 134 * <p/> 135 * <ul> 136 * <li><code>config/sun_checks.xml</code>: Sun Checks.</li> 137 * <li><code>config/turbine_checks.xml</code>: Turbine Checks.</li> 138 * <li><code>config/avalon_checks.xml</code>: Avalon Checks.</li> 139 * <li><code>config/maven_checks.xml</code>: Maven Source Checks.</li> 140 * </ul> 141 */ 142 @Parameter( property = "checkstyle.config.location", defaultValue = "config/sun_checks.xml" ) 143 private String configLocation; 144 145 /** 146 * Specifies what predefined check set to use. Available sets are "sun" (for 147 * the Sun coding conventions), "turbine", and "avalon". 148 * 149 * @deprecated Use configLocation instead. 150 */ 151 @Parameter( defaultValue = "sun" ) 152 private String format; 153 154 /** 155 * <p> 156 * Specifies the location of the properties file. 157 * </p> 158 * <p/> 159 * <p> 160 * This parameter is resolved as URL, File then resource. If successfully 161 * resolved, the contents of the properties location is copied into the 162 * <code>${project.build.directory}/checkstyle-checker.properties</code> 163 * file before being passed to Checkstyle for loading. 164 * </p> 165 * <p/> 166 * <p> 167 * The contents of the <code>propertiesLocation</code> will be made 168 * available to Checkstyle for specifying values for parameters within the 169 * xml configuration (specified in the <code>configLocation</code> 170 * parameter). 171 * </p> 172 * 173 * @since 2.0-beta-2 174 */ 175 @Parameter( property = "checkstyle.properties.location" ) 176 private String propertiesLocation; 177 178 /** 179 * Specifies the location of the Checkstyle properties file that will be used to 180 * check the source. 181 * 182 * @deprecated Use propertiesLocation instead. 183 */ 184 @Parameter 185 private File propertiesFile; 186 187 /** 188 * Specifies the URL of the Checkstyle properties that will be used to check 189 * the source. 190 * 191 * @deprecated Use propertiesLocation instead. 192 */ 193 @Parameter 194 private URL propertiesURL; 195 196 /** 197 * Allows for specifying raw property expansion information. 198 */ 199 @Parameter 200 private String propertyExpansion; 201 202 /** 203 * <p> 204 * Specifies the location of the License file (a.k.a. the header file) that 205 * can be used by Checkstyle to verify that source code has the correct 206 * license header. 207 * </p> 208 * <p> 209 * You need to use ${checkstyle.header.file} in your Checkstyle xml 210 * configuration to reference the name of this header file. 211 * </p> 212 * <p> 213 * For instance: 214 * </p> 215 * <p> 216 * <code> 217 * <module name="RegexpHeader"> 218 * <property name="headerFile" value="${checkstyle.header.file}"/> 219 * </module> 220 * </code> 221 * </p> 222 * 223 * @since 2.0-beta-2 224 */ 225 @Parameter( property = "checkstyle.header.file", defaultValue = "LICENSE.txt" ) 226 private String headerLocation; 227 228 /** 229 * Specifies the location of the License file (a.k.a. the header file) that 230 * is used by Checkstyle to verify that source code has the correct 231 * license header. 232 * 233 * @deprecated Use headerLocation instead. 234 */ 235 @Parameter( defaultValue = "${basedir}/LICENSE.txt" ) 236 private File headerFile; 237 238 /** 239 * Specifies the cache file used to speed up Checkstyle on successive runs. 240 */ 241 @Parameter( defaultValue = "${project.build.directory}/checkstyle-cachefile" ) 242 private String cacheFile; 243 244 /** 245 * <p> 246 * Specifies the location of the suppressions XML file to use. 247 * </p> 248 * <p/> 249 * <p> 250 * This parameter is resolved as resource, URL, then file. If successfully 251 * resolved, the contents of the suppressions XML is copied into the 252 * <code>${project.build.directory}/checkstyle-supressions.xml</code> file 253 * before being passed to Checkstyle for loading. 254 * </p> 255 * <p/> 256 * <p> 257 * See <code>suppressionsFileExpression</code> for the property that will 258 * be made available to your checkstyle configuration. 259 * </p> 260 * 261 * @since 2.0-beta-2 262 */ 263 @Parameter( property = "checkstyle.suppressions.location" ) 264 private String suppressionsLocation; 265 266 /** 267 * The key to be used in the properties for the suppressions file. 268 * 269 * @since 2.1 270 */ 271 @Parameter( property = "checkstyle.suppression.expression", defaultValue = "checkstyle.suppressions.file" ) 272 private String suppressionsFileExpression; 273 274 /** 275 * Specifies the location of the suppressions XML file to use. The plugin 276 * defines a Checkstyle property named 277 * <code>checkstyle.suppressions.file</code> with the value of this 278 * property. This allows using the Checkstyle property in your own custom 279 * checkstyle configuration file when specifying a suppressions file. 280 * 281 * @deprecated Use suppressionsLocation instead. 282 */ 283 @Parameter 284 private String suppressionsFile; 285 286 /** 287 * <p> 288 * Specifies the location of the package names XML to be used to configure 289 * the Checkstyle <a 290 * href="http://checkstyle.sourceforge.net/config.html#Packages">Packages</a>. 291 * </p> 292 * <p/> 293 * <p> 294 * This parameter is resolved as resource, URL, then file. If resolved to a 295 * resource, or a URL, the contents of the package names XML is copied into 296 * the <code>${project.build.directory}/checkstyle-packagenames.xml</code> 297 * file before being passed to Checkstyle for loading. 298 * </p> 299 * 300 * @since 2.0-beta-2 301 */ 302 @Parameter 303 private String packageNamesLocation; 304 305 /** 306 * Specifies the location of the package names XML to be used to configure 307 * Checkstyle. 308 * 309 * @deprecated Use packageNamesLocation instead. 310 */ 311 @Parameter 312 private String packageNamesFile; 313 314 /** 315 * Specifies if the build should fail upon a violation. 316 */ 317 @Parameter( defaultValue = "false" ) 318 private boolean failsOnError; 319 320 /** 321 * Specifies the location of the source directory to be used for Checkstyle. 322 */ 323 @Parameter( defaultValue = "${project.build.sourceDirectory}", required = true ) 324 private File sourceDirectory; 325 326 /** 327 * Specifies the location of the test source directory to be used for 328 * Checkstyle. 329 * 330 * @since 2.2 331 */ 332 @Parameter( defaultValue = "${project.build.testSourceDirectory}" ) 333 private File testSourceDirectory; 334 335 /** 336 * Include or not the test source directory to be used for Checkstyle. 337 * 338 * @since 2.2 339 */ 340 @Parameter( defaultValue = "false" ) 341 private boolean includeTestSourceDirectory; 342 343 /** 344 * Output errors to console. 345 */ 346 @Parameter( defaultValue = "false" ) 347 private boolean consoleOutput; 348 349 /** 350 * The file encoding to use when reading the source files. If the property <code>project.build.sourceEncoding</code> 351 * is not set, the platform default encoding is used. <strong>Note:</strong> This parameter always overrides the 352 * property <code>charset</code> from Checkstyle's <code>TreeWalker</code> module. 353 * 354 * @since 2.2 355 */ 356 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" ) 357 private String encoding; 358 359 /** {@inheritDoc} */ 360 protected MavenProject getProject() 361 { 362 return project; 363 } 364 365 /** {@inheritDoc} */ 366 public void executeReport( Locale locale ) 367 throws MavenReportException 368 { 369 mergeDeprecatedInfo(); 370 super.executeReport( locale ); 371 } 372 373 /** 374 * {@inheritDoc} 375 */ 376 protected CheckstyleExecutorRequest createRequest() 377 throws MavenReportException 378 { 379 CheckstyleExecutorRequest request = new CheckstyleExecutorRequest(); 380 request.setConsoleListener( getConsoleListener() ).setConsoleOutput( consoleOutput ) 381 .setExcludes( excludes ).setFailsOnError( failsOnError ).setIncludes( includes ) 382 .setResourceIncludes( resourceIncludes ) 383 .setResourceExcludes( resourceExcludes ) 384 .setIncludeResources( includeResources ) 385 .setIncludeTestResources( includeTestResources ) 386 .setIncludeTestSourceDirectory( includeTestSourceDirectory ).setListener( getListener() ) 387 .setLog( getLog() ).setProject( project ).setSourceDirectory( sourceDirectory ).setResources( resources ) 388 .setStringOutputStream( stringOutputStream ).setSuppressionsLocation( suppressionsLocation ) 389 .setTestSourceDirectory( testSourceDirectory ).setConfigLocation( configLocation ) 390 .setPropertyExpansion( propertyExpansion ).setHeaderLocation( headerLocation ) 391 .setCacheFile( cacheFile ).setSuppressionsFileExpression( suppressionsFileExpression ) 392 .setEncoding( encoding ).setPropertiesLocation( propertiesLocation ); 393 return request; 394 } 395 396 /** {@inheritDoc} */ 397 public String getOutputName() 398 { 399 return "checkstyle"; 400 } 401 402 /** {@inheritDoc} */ 403 public boolean canGenerateReport() 404 { 405 // TODO: would be good to scan the files here 406 return !skip && ( sourceDirectory.exists() || ( includeTestSourceDirectory && testSourceDirectory.exists() ) ); 407 } 408 409 /** 410 * Merge in the deprecated parameters to the new ones, unless the new 411 * parameters have values. 412 * 413 * @deprecated Remove when deprecated params are removed. 414 */ 415 private void mergeDeprecatedInfo() 416 { 417 if ( "config/sun_checks.xml".equals( configLocation ) && !"sun".equals( format ) ) 418 { 419 configLocation = FORMAT_TO_CONFIG_LOCATION.get( format ); 420 } 421 422 if ( StringUtils.isEmpty( propertiesLocation ) ) 423 { 424 if ( propertiesFile != null ) 425 { 426 propertiesLocation = propertiesFile.getPath(); 427 } 428 else if ( propertiesURL != null ) 429 { 430 propertiesLocation = propertiesURL.toExternalForm(); 431 } 432 } 433 434 if ( "LICENSE.txt".equals( headerLocation ) ) 435 { 436 File defaultHeaderFile = new File( project.getBasedir(), "LICENSE.txt" ); 437 if ( !defaultHeaderFile.equals( headerFile ) ) 438 { 439 headerLocation = headerFile.getPath(); 440 } 441 } 442 443 if ( StringUtils.isEmpty( suppressionsLocation ) ) 444 { 445 suppressionsLocation = suppressionsFile; 446 } 447 448 if ( StringUtils.isEmpty( packageNamesLocation ) ) 449 { 450 packageNamesLocation = packageNamesFile; 451 } 452 } 453 454 }