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 * <module name="RegexpHeader">
190 * <property name="headerFile" value="${checkstyle.header.file}"/>
191 * </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 }