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 * Perform a Checkstyle analysis, and generate a report on violations. 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 1429846 2013-01-07 15:37:24Z dennisl $ 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 * <p> 82 * Specifies the location of the XML configuration to use. 83 * </p> 84 * <p/> 85 * <p> 86 * Potential values are a filesystem path, a URL, or a classpath resource. 87 * This parameter expects that the contents of the location conform to the 88 * xml format (Checkstyle <a 89 * href="http://checkstyle.sourceforge.net/config.html#Modules">Checker 90 * module</a>) configuration of rulesets. 91 * </p> 92 * <p/> 93 * <p> 94 * This parameter is resolved as resource, URL, then file. If successfully 95 * resolved, the contents of the configuration is copied into the 96 * <code>${project.build.directory}/checkstyle-configuration.xml</code> 97 * file before being passed to Checkstyle as a configuration. 98 * </p> 99 * <p/> 100 * <p> 101 * There are 4 predefined rulesets. 102 * </p> 103 * <p/> 104 * <ul> 105 * <li><code>config/sun_checks.xml</code>: Sun Checks.</li> 106 * <li><code>config/turbine_checks.xml</code>: Turbine Checks.</li> 107 * <li><code>config/avalon_checks.xml</code>: Avalon Checks.</li> 108 * <li><code>config/maven_checks.xml</code>: Maven Source Checks.</li> 109 * </ul> 110 */ 111 @Parameter( property = "checkstyle.config.location", defaultValue = "config/sun_checks.xml" ) 112 private String configLocation; 113 114 /** 115 * Specifies what predefined check set to use. Available sets are "sun" (for 116 * the Sun coding conventions), "turbine", and "avalon". 117 * 118 * @deprecated Use configLocation instead. 119 */ 120 @Parameter( defaultValue = "sun" ) 121 private String format; 122 123 /** 124 * <p> 125 * Specifies the location of the properties file. 126 * </p> 127 * <p/> 128 * <p> 129 * This parameter is resolved as URL, File then resource. If successfully 130 * resolved, the contents of the properties location is copied into the 131 * <code>${project.build.directory}/checkstyle-checker.properties</code> 132 * file before being passed to Checkstyle for loading. 133 * </p> 134 * <p/> 135 * <p> 136 * The contents of the <code>propertiesLocation</code> will be made 137 * available to Checkstyle for specifying values for parameters within the 138 * xml configuration (specified in the <code>configLocation</code> 139 * parameter). 140 * </p> 141 * 142 * @since 2.0-beta-2 143 */ 144 @Parameter( property = "checkstyle.properties.location" ) 145 private String propertiesLocation; 146 147 /** 148 * Specifies the location of the Checkstyle properties file that will be used to 149 * check the source. 150 * 151 * @deprecated Use propertiesLocation instead. 152 */ 153 @Parameter 154 private File propertiesFile; 155 156 /** 157 * Specifies the URL of the Checkstyle properties that will be used to check 158 * the source. 159 * 160 * @deprecated Use propertiesLocation instead. 161 */ 162 @Parameter 163 private URL propertiesURL; 164 165 /** 166 * Allows for specifying raw property expansion information. 167 */ 168 @Parameter 169 private String propertyExpansion; 170 171 /** 172 * <p> 173 * Specifies the location of the License file (a.k.a. the header file) that 174 * can be used by Checkstyle to verify that source code has the correct 175 * license header. 176 * </p> 177 * <p> 178 * You need to use ${checkstyle.header.file} in your Checkstyle xml 179 * configuration to reference the name of this header file. 180 * </p> 181 * <p> 182 * For instance: 183 * </p> 184 * <p> 185 * <code> 186 * <module name="RegexpHeader"> 187 * <property name="headerFile" value="${checkstyle.header.file}"/> 188 * </module> 189 * </code> 190 * </p> 191 * 192 * @since 2.0-beta-2 193 */ 194 @Parameter( property = "checkstyle.header.file", defaultValue = "LICENSE.txt" ) 195 private String headerLocation; 196 197 /** 198 * Specifies the location of the License file (a.k.a. the header file) that 199 * is used by Checkstyle to verify that source code has the correct 200 * license header. 201 * 202 * @deprecated Use headerLocation instead. 203 */ 204 @Parameter( defaultValue = "${basedir}/LICENSE.txt" ) 205 private File headerFile; 206 207 /** 208 * Specifies the cache file used to speed up Checkstyle on successive runs. 209 */ 210 @Parameter( defaultValue = "${project.build.directory}/checkstyle-cachefile" ) 211 private String cacheFile; 212 213 /** 214 * <p> 215 * Specifies the location of the suppressions XML file to use. 216 * </p> 217 * <p/> 218 * <p> 219 * This parameter is resolved as resource, URL, then file. If successfully 220 * resolved, the contents of the suppressions XML is copied into the 221 * <code>${project.build.directory}/checkstyle-supressions.xml</code> file 222 * before being passed to Checkstyle for loading. 223 * </p> 224 * <p/> 225 * <p> 226 * See <code>suppressionsFileExpression</code> for the property that will 227 * be made available to your checkstyle configuration. 228 * </p> 229 * 230 * @since 2.0-beta-2 231 */ 232 @Parameter( property = "checkstyle.suppressions.location" ) 233 private String suppressionsLocation; 234 235 /** 236 * The key to be used in the properties for the suppressions file. 237 * 238 * @since 2.1 239 */ 240 @Parameter( property = "checkstyle.suppression.expression", defaultValue = "checkstyle.suppressions.file" ) 241 private String suppressionsFileExpression; 242 243 /** 244 * Specifies the location of the suppressions XML file to use. The plugin 245 * defines a Checkstyle property named 246 * <code>checkstyle.suppressions.file</code> with the value of this 247 * property. This allows using the Checkstyle property in your own custom 248 * checkstyle configuration file when specifying a suppressions file. 249 * 250 * @deprecated Use suppressionsLocation instead. 251 */ 252 @Parameter 253 private String suppressionsFile; 254 255 /** 256 * <p> 257 * Specifies the location of the package names XML to be used to configure 258 * the Checkstyle <a 259 * href="http://checkstyle.sourceforge.net/config.html#Packages">Packages</a>. 260 * </p> 261 * <p/> 262 * <p> 263 * This parameter is resolved as resource, URL, then file. If resolved to a 264 * resource, or a URL, the contents of the package names XML is copied into 265 * the <code>${project.build.directory}/checkstyle-packagenames.xml</code> 266 * file before being passed to Checkstyle for loading. 267 * </p> 268 * 269 * @since 2.0-beta-2 270 */ 271 @Parameter 272 private String packageNamesLocation; 273 274 /** 275 * Specifies the location of the package names XML to be used to configure 276 * Checkstyle. 277 * 278 * @deprecated Use packageNamesLocation instead. 279 */ 280 @Parameter 281 private String packageNamesFile; 282 283 /** 284 * Specifies if the build should fail upon a violation. 285 */ 286 @Parameter( defaultValue = "false" ) 287 private boolean failsOnError; 288 289 /** 290 * Specifies the location of the source directory to be used for Checkstyle. 291 */ 292 @Parameter( defaultValue = "${project.build.sourceDirectory}", required = true ) 293 private File sourceDirectory; 294 295 /** 296 * Specifies the location of the test source directory to be used for 297 * Checkstyle. 298 * 299 * @since 2.2 300 */ 301 @Parameter( defaultValue = "${project.build.testSourceDirectory}" ) 302 private File testSourceDirectory; 303 304 /** 305 * Include or not the test source directory to be used for Checkstyle. 306 * 307 * @since 2.2 308 */ 309 @Parameter( defaultValue = "false" ) 310 private boolean includeTestSourceDirectory; 311 312 /** 313 * Output errors to console. 314 */ 315 @Parameter( defaultValue = "false" ) 316 private boolean consoleOutput; 317 318 /** 319 * The file encoding to use when reading the source files. If the property <code>project.build.sourceEncoding</code> 320 * is not set, the platform default encoding is used. <strong>Note:</strong> This parameter always overrides the 321 * property <code>charset</code> from Checkstyle's <code>TreeWalker</code> module. 322 * 323 * @since 2.2 324 */ 325 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" ) 326 private String encoding; 327 328 /** {@inheritDoc} */ 329 protected MavenProject getProject() 330 { 331 return project; 332 } 333 334 /** {@inheritDoc} */ 335 public void executeReport( Locale locale ) 336 throws MavenReportException 337 { 338 mergeDeprecatedInfo(); 339 super.executeReport( locale ); 340 } 341 342 /** 343 * {@inheritDoc} 344 */ 345 protected CheckstyleExecutorRequest createRequest() 346 throws MavenReportException 347 { 348 CheckstyleExecutorRequest request = new CheckstyleExecutorRequest(); 349 request.setConsoleListener( getConsoleListener() ).setConsoleOutput( consoleOutput ) 350 .setExcludes( excludes ).setFailsOnError( failsOnError ).setIncludes( includes ) 351 .setIncludeTestSourceDirectory( includeTestSourceDirectory ).setListener( getListener() ) 352 .setLog( getLog() ).setProject( project ).setSourceDirectory( sourceDirectory ).setResources( resources ) 353 .setStringOutputStream( stringOutputStream ).setSuppressionsLocation( suppressionsLocation ) 354 .setTestSourceDirectory( testSourceDirectory ).setConfigLocation( configLocation ) 355 .setPropertyExpansion( propertyExpansion ).setHeaderLocation( headerLocation ) 356 .setCacheFile( cacheFile ).setSuppressionsFileExpression( suppressionsFileExpression ) 357 .setEncoding( encoding ).setPropertiesLocation( propertiesLocation ); 358 return request; 359 } 360 361 /** {@inheritDoc} */ 362 public String getOutputName() 363 { 364 return "checkstyle"; 365 } 366 367 /** {@inheritDoc} */ 368 public boolean canGenerateReport() 369 { 370 // TODO: would be good to scan the files here 371 return !skip && ( sourceDirectory.exists() || ( includeTestSourceDirectory && testSourceDirectory.exists() ) ); 372 } 373 374 /** 375 * Merge in the deprecated parameters to the new ones, unless the new 376 * parameters have values. 377 * 378 * @deprecated Remove when deprecated params are removed. 379 */ 380 private void mergeDeprecatedInfo() 381 { 382 if ( "config/sun_checks.xml".equals( configLocation ) && !"sun".equals( format ) ) 383 { 384 configLocation = (String) FORMAT_TO_CONFIG_LOCATION.get( format ); 385 } 386 387 if ( StringUtils.isEmpty( propertiesLocation ) ) 388 { 389 if ( propertiesFile != null ) 390 { 391 propertiesLocation = propertiesFile.getPath(); 392 } 393 else if ( propertiesURL != null ) 394 { 395 propertiesLocation = propertiesURL.toExternalForm(); 396 } 397 } 398 399 if ( "LICENSE.txt".equals( headerLocation ) ) 400 { 401 File defaultHeaderFile = new File( project.getBasedir(), "LICENSE.txt" ); 402 if ( !defaultHeaderFile.equals( headerFile ) ) 403 { 404 headerLocation = headerFile.getPath(); 405 } 406 } 407 408 if ( StringUtils.isEmpty( suppressionsLocation ) ) 409 { 410 suppressionsLocation = suppressionsFile; 411 } 412 413 if ( StringUtils.isEmpty( packageNamesLocation ) ) 414 { 415 packageNamesLocation = packageNamesFile; 416 } 417 } 418 419 }