1 package org.apache.maven.plugin.checkstyle;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.OutputStream;
28 import java.util.Calendar;
29 import java.util.Iterator;
30 import java.util.Locale;
31 import java.util.ResourceBundle;
32
33 import org.apache.maven.doxia.siterenderer.Renderer;
34 import org.apache.maven.doxia.tools.SiteTool;
35 import org.apache.maven.model.ReportPlugin;
36 import org.apache.maven.plugin.checkstyle.rss.CheckstyleRssGenerator;
37 import org.apache.maven.plugin.checkstyle.rss.CheckstyleRssGeneratorRequest;
38 import org.apache.maven.project.MavenProject;
39 import org.apache.maven.reporting.AbstractMavenReport;
40 import org.apache.maven.reporting.MavenReportException;
41 import org.codehaus.plexus.resource.ResourceManager;
42 import org.codehaus.plexus.resource.loader.FileResourceLoader;
43 import org.codehaus.plexus.util.PathTool;
44 import org.codehaus.plexus.util.StringUtils;
45
46 import com.puppycrawl.tools.checkstyle.DefaultLogger;
47 import com.puppycrawl.tools.checkstyle.XMLLogger;
48 import com.puppycrawl.tools.checkstyle.api.AuditListener;
49 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
50
51
52
53
54
55
56
57 public abstract class AbstractCheckstyleReport
58 extends AbstractMavenReport
59 {
60 public static final String PLUGIN_RESOURCES = "org/apache/maven/plugin/checkstyle";
61
62
63
64
65
66
67
68 protected boolean skip;
69
70
71
72
73
74
75
76
77
78
79 private File outputDirectory;
80
81
82
83
84
85
86
87
88
89 private File outputFile;
90
91
92
93
94
95
96
97 private File useFile;
98
99
100
101
102
103
104
105 private String outputFileFormat;
106
107
108
109
110
111
112
113 private boolean enableRulesSummary;
114
115
116
117
118
119
120
121 private boolean enableSeveritySummary;
122
123
124
125
126
127
128
129 private boolean enableFilesSummary;
130
131
132
133
134
135
136 private boolean enableRSS;
137
138
139
140
141
142
143
144
145
146 protected SiteTool siteTool;
147
148
149
150
151
152
153
154
155 protected MavenProject project;
156
157
158
159
160
161
162
163
164 private boolean linkXRef;
165
166
167
168
169
170
171 private File xrefLocation;
172
173
174
175
176
177
178 private Renderer siteRenderer;
179
180
181
182
183
184
185 protected ResourceManager locator;
186
187
188
189
190
191
192
193
194
195 protected CheckstyleRssGenerator checkstyleRssGenerator;
196
197
198
199
200
201
202
203 protected CheckstyleExecutor checkstyleExecutor;
204
205 protected ByteArrayOutputStream stringOutputStream;
206
207
208 public String getName( Locale locale )
209 {
210 return getBundle( locale ).getString( "report.checkstyle.name" );
211 }
212
213
214 public String getDescription( Locale locale )
215 {
216 return getBundle( locale ).getString( "report.checkstyle.description" );
217 }
218
219
220 protected String getOutputDirectory()
221 {
222 return outputDirectory.getAbsolutePath();
223 }
224
225
226 protected MavenProject getProject()
227 {
228 return project;
229 }
230
231
232 protected Renderer getSiteRenderer()
233 {
234 return siteRenderer;
235 }
236
237
238 public void executeReport( Locale locale )
239 throws MavenReportException
240 {
241 locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() );
242 locator.addSearchPath( "url", "" );
243
244 locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) );
245
246
247
248
249
250
251
252
253 ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
254
255 try
256 {
257 CheckstyleExecutorRequest request = createRequest();
258
259 CheckstyleResults results = checkstyleExecutor.executeCheckstyle( request );
260
261 ResourceBundle bundle = getBundle( locale );
262 generateReportStatics();
263 generateMainReport( results, bundle );
264 if ( enableRSS )
265 {
266 CheckstyleRssGeneratorRequest checkstyleRssGeneratorRequest =
267 new CheckstyleRssGeneratorRequest( this.project, this.getCopyright(), outputDirectory, getLog() );
268 checkstyleRssGenerator.generateRSS( results, checkstyleRssGeneratorRequest );
269 }
270
271 }
272 catch ( CheckstyleException e )
273 {
274 throw new MavenReportException( "Failed during checkstyle configuration", e );
275 }
276 catch ( CheckstyleExecutorException e )
277 {
278 throw new MavenReportException( "Failed during checkstyle execution", e );
279 }
280 finally
281 {
282
283 Thread.currentThread().setContextClassLoader( currentClassLoader );
284 }
285 }
286
287
288
289
290
291
292
293 protected abstract CheckstyleExecutorRequest createRequest()
294 throws MavenReportException;
295
296
297
298
299
300
301
302 protected AuditListener getListener()
303 throws MavenReportException
304 {
305 AuditListener listener = null;
306
307 if ( StringUtils.isNotEmpty( outputFileFormat ) )
308 {
309 File resultFile = outputFile;
310
311 OutputStream out = getOutputStream( resultFile );
312
313 if ( "xml".equals( outputFileFormat ) )
314 {
315 listener = new XMLLogger( out, true );
316 }
317 else if ( "plain".equals( outputFileFormat ) )
318 {
319 listener = new DefaultLogger( out, true );
320 }
321 else
322 {
323
324 throw new MavenReportException( "Invalid output file format: (" + outputFileFormat
325 + "). Must be 'plain' or 'xml'." );
326 }
327 }
328
329 return listener;
330 }
331
332 private OutputStream getOutputStream( File file )
333 throws MavenReportException
334 {
335 File parentFile = file.getAbsoluteFile().getParentFile();
336
337 if ( !parentFile.exists() )
338 {
339 parentFile.mkdirs();
340 }
341
342 FileOutputStream fileOutputStream;
343 try
344 {
345 fileOutputStream = new FileOutputStream( file );
346 }
347 catch ( FileNotFoundException e )
348 {
349 throw new MavenReportException( "Unable to create output stream: " + file, e );
350 }
351 return fileOutputStream;
352 }
353
354
355
356
357
358
359
360 protected DefaultLogger getConsoleListener()
361 throws MavenReportException
362 {
363 DefaultLogger consoleListener;
364
365 if ( useFile == null )
366 {
367 stringOutputStream = new ByteArrayOutputStream();
368 consoleListener = new DefaultLogger( stringOutputStream, false );
369 }
370 else
371 {
372 OutputStream out = getOutputStream( useFile );
373
374 consoleListener = new DefaultLogger( out, true );
375 }
376
377 return consoleListener;
378 }
379
380 private void generateReportStatics()
381 throws MavenReportException
382 {
383 ReportResource rresource = new ReportResource( PLUGIN_RESOURCES, outputDirectory );
384 try
385 {
386 rresource.copy( "images/rss.png" );
387 }
388 catch ( IOException e )
389 {
390 throw new MavenReportException( "Unable to copy static resources.", e );
391 }
392 }
393
394
395 private String getCopyright()
396 {
397 String copyright;
398 int currentYear = Calendar.getInstance().get( Calendar.YEAR );
399 if ( StringUtils.isNotEmpty( project.getInceptionYear() )
400 && !String.valueOf( currentYear ).equals( project.getInceptionYear() ) )
401 {
402 copyright = project.getInceptionYear() + " - " + currentYear;
403 }
404 else
405 {
406 copyright = String.valueOf( currentYear );
407 }
408
409 if ( ( project.getOrganization() != null ) && StringUtils.isNotEmpty( project.getOrganization().getName() ) )
410 {
411 copyright = copyright + " " + project.getOrganization().getName();
412 }
413 return copyright;
414 }
415
416 private void generateMainReport( CheckstyleResults results, ResourceBundle bundle )
417 {
418 CheckstyleReportGenerator generator =
419 new CheckstyleReportGenerator( getSink(), bundle, project.getBasedir(), siteTool );
420
421 generator.setLog( getLog() );
422 generator.setEnableRulesSummary( enableRulesSummary );
423 generator.setEnableSeveritySummary( enableSeveritySummary );
424 generator.setEnableFilesSummary( enableFilesSummary );
425 generator.setEnableRSS( enableRSS );
426 generator.setCheckstyleConfig( results.getConfiguration() );
427 if ( linkXRef )
428 {
429 String relativePath = PathTool.getRelativePath( getOutputDirectory(), xrefLocation.getAbsolutePath() );
430 if ( StringUtils.isEmpty( relativePath ) )
431 {
432 relativePath = ".";
433 }
434 relativePath = relativePath + "/" + xrefLocation.getName();
435 if ( xrefLocation.exists() )
436 {
437
438
439 generator.setXrefLocation( relativePath );
440 }
441 else
442 {
443
444 for ( Iterator<ReportPlugin> reports = getProject().getReportPlugins().iterator(); reports.hasNext(); )
445 {
446 ReportPlugin report = reports.next();
447
448 String artifactId = report.getArtifactId();
449 if ( "maven-jxr-plugin".equals( artifactId ) || "jxr-maven-plugin".equals( artifactId ) )
450 {
451 generator.setXrefLocation( relativePath );
452 }
453 }
454 }
455
456 if ( generator.getXrefLocation() == null )
457 {
458 getLog().warn( "Unable to locate Source XRef to link to - DISABLED" );
459 }
460 }
461 generator.generateReport( results );
462 }
463
464 private static ResourceBundle getBundle( Locale locale )
465 {
466 return ResourceBundle.getBundle( "checkstyle-report", locale, AbstractCheckstyleReport.class.getClassLoader() );
467 }
468
469
470 public void setReportOutputDirectory( File reportOutputDirectory )
471 {
472 super.setReportOutputDirectory( reportOutputDirectory );
473 this.outputDirectory = reportOutputDirectory;
474 }
475 }