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