View Javadoc

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      * &lt;module name="RegexpHeader">
187      * &lt;property name="headerFile" value="${checkstyle.header.file}"/>
188      * &lt;/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 }