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