1 package org.apache.maven.plugin.pmd;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.LinkedHashSet;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.TreeMap;
34
35 import net.sourceforge.pmd.PMD;
36
37 import org.apache.maven.doxia.siterenderer.Renderer;
38 import org.apache.maven.model.ReportPlugin;
39 import org.apache.maven.project.MavenProject;
40 import org.apache.maven.reporting.AbstractMavenReport;
41 import org.codehaus.plexus.util.FileUtils;
42 import org.codehaus.plexus.util.PathTool;
43 import org.codehaus.plexus.util.ReaderFactory;
44 import org.codehaus.plexus.util.StringUtils;
45
46
47
48
49
50
51
52 public abstract class AbstractPmdReport
53 extends AbstractMavenReport
54 {
55
56
57
58
59
60
61 protected File targetDirectory;
62
63
64
65
66
67
68
69
70
71 protected File outputDirectory;
72
73
74
75
76
77
78 private Renderer siteRenderer;
79
80
81
82
83
84
85
86
87 protected MavenProject project;
88
89
90
91
92
93
94
95
96
97 protected String format = "xml";
98
99
100
101
102
103
104
105 private boolean linkXRef;
106
107
108
109
110
111
112 private File xrefLocation;
113
114
115
116
117
118
119 private File xrefTestLocation;
120
121
122
123
124
125
126
127
128
129
130 private String[] excludes;
131
132
133
134
135
136
137
138
139 private String[] includes;
140
141
142
143
144
145
146
147
148 private List compileSourceRoots;
149
150
151
152
153
154
155
156
157 private List testSourceRoots;
158
159
160
161
162
163
164
165 private File[] excludeRoots;
166
167
168
169
170
171
172
173 protected boolean includeTests;
174
175
176
177
178
179
180
181 protected boolean aggregate;
182
183
184
185
186
187
188
189 private String sourceEncoding;
190
191
192
193
194
195
196
197 private String outputEncoding;
198
199
200
201
202
203
204
205 protected List reactorProjects;
206
207
208 protected MavenProject getProject()
209 {
210 return project;
211 }
212
213
214 protected Renderer getSiteRenderer()
215 {
216 return siteRenderer;
217 }
218
219 protected String constructXRefLocation( boolean test )
220 {
221 String location = null;
222 if ( linkXRef )
223 {
224 File xrefLoc = test ? xrefTestLocation : xrefLocation;
225
226 String relativePath = PathTool.getRelativePath( outputDirectory.getAbsolutePath(), xrefLoc.getAbsolutePath() );
227 if ( StringUtils.isEmpty( relativePath ) )
228 {
229 relativePath = ".";
230 }
231 relativePath = relativePath + "/" + xrefLoc.getName();
232 if ( xrefLoc.exists() )
233 {
234
235 location = relativePath;
236 }
237 else
238 {
239
240 for ( Iterator reports = project.getReportPlugins().iterator(); reports.hasNext(); )
241 {
242 ReportPlugin plugin = (ReportPlugin) reports.next();
243
244 String artifactId = plugin.getArtifactId();
245 if ( "maven-jxr-plugin".equals( artifactId ) || "jxr-maven-plugin".equals( artifactId ) )
246 {
247 location = relativePath;
248 }
249 }
250 }
251
252 if ( location == null )
253 {
254 getLog().warn( "Unable to locate Source XRef to link to - DISABLED" );
255 }
256 }
257 return location;
258 }
259
260
261
262
263
264
265
266 protected Map getFilesToProcess()
267 throws IOException
268 {
269 String sourceXref = constructXRefLocation( false );
270 String testXref = includeTests ? constructXRefLocation( true ) : "";
271
272 if ( aggregate && !project.isExecutionRoot() )
273 {
274 return Collections.EMPTY_MAP;
275 }
276
277 if ( excludeRoots == null )
278 {
279 excludeRoots = new File[0];
280 }
281 Collection excludeRootFiles = new HashSet( excludeRoots.length );
282
283 for ( int i = 0; i < excludeRoots.length; i++ )
284 {
285 File file = excludeRoots[i];
286 if ( file.isDirectory() )
287 {
288 excludeRootFiles.add( file );
289 }
290 }
291
292 List directories = new ArrayList();
293
294 if ( compileSourceRoots != null )
295 {
296
297 for ( Iterator i = compileSourceRoots.iterator(); i.hasNext(); )
298 {
299 String root = (String) i.next();
300 File sroot = new File( root );
301 directories.add( new PmdFileInfo( project, sroot, sourceXref ) );
302 }
303
304 }
305 if ( includeTests )
306 {
307 if ( testSourceRoots != null )
308 {
309 for ( Iterator i = testSourceRoots.iterator(); i.hasNext(); )
310 {
311 String root = (String) i.next();
312 File sroot = new File( root );
313 directories.add( new PmdFileInfo( project, sroot, testXref ) );
314 }
315 }
316 }
317 if ( aggregate )
318 {
319 for ( Iterator i = reactorProjects.iterator(); i.hasNext(); )
320 {
321 MavenProject localProject = (MavenProject) i.next();
322 for ( Iterator i2 = localProject.getCompileSourceRoots().iterator(); i2.hasNext(); )
323 {
324 String root = (String) i2.next();
325 File sroot = new File( root );
326 directories.add( new PmdFileInfo( localProject, sroot, sourceXref ) );
327 }
328 if ( includeTests )
329 {
330 for ( Iterator i2 = localProject.getTestCompileSourceRoots().iterator(); i2.hasNext(); )
331 {
332 String root = (String) i2.next();
333 File sroot = new File( root );
334 directories.add( new PmdFileInfo( localProject, sroot, testXref ) );
335 }
336 }
337 }
338
339 }
340
341 String excluding = getExcludes();
342 getLog().debug( "Exclusions: " + excluding );
343 String including = getIncludes();
344 getLog().debug( "Inclusions: " + including );
345
346 Map files = new TreeMap();
347
348 for ( Iterator it = directories.iterator(); it.hasNext(); )
349 {
350 PmdFileInfo finfo = (PmdFileInfo) it.next();
351 File sourceDirectory = finfo.getSourceDirectory();
352 if ( sourceDirectory.isDirectory() && !excludeRootFiles.contains( sourceDirectory ) )
353 {
354 List newfiles = FileUtils.getFiles( sourceDirectory, including, excluding );
355 for ( Iterator it2 = newfiles.iterator(); it2.hasNext(); )
356 {
357 files.put( it2.next(), finfo );
358 }
359 }
360 }
361
362 return files;
363 }
364
365
366
367
368
369
370 private String getIncludes()
371 {
372 Collection patterns = new LinkedHashSet();
373 if ( includes != null )
374 {
375 patterns.addAll( Arrays.asList( includes ) );
376 }
377 if ( patterns.isEmpty() )
378 {
379 patterns.add( "**/*.java" );
380 }
381 return StringUtils.join( patterns.iterator(), "," );
382 }
383
384
385
386
387
388
389 private String getExcludes()
390 {
391 Collection patterns = new LinkedHashSet( FileUtils.getDefaultExcludesAsList() );
392 if ( excludes != null )
393 {
394 patterns.addAll( Arrays.asList( excludes ) );
395 }
396 return StringUtils.join( patterns.iterator(), "," );
397 }
398
399 protected boolean isHtml()
400 {
401 return "html".equals( format );
402 }
403
404
405 public boolean canGenerateReport()
406 {
407 if ( aggregate && !project.isExecutionRoot() )
408 {
409 return false;
410 }
411
412 if ( "pom".equals( project.getPackaging() ) && !aggregate )
413 {
414 return false;
415 }
416
417
418
419 if ( "xml".equals( format ) )
420 {
421 return true;
422 }
423 try
424 {
425 Map filesToProcess = getFilesToProcess();
426 if ( filesToProcess.isEmpty() )
427 {
428 return false;
429 }
430 }
431 catch ( IOException e )
432 {
433 getLog().error( e );
434 }
435 return true;
436 }
437
438
439 protected String getOutputDirectory()
440 {
441 return outputDirectory.getAbsolutePath();
442 }
443
444 protected String getSourceEncoding()
445 {
446 return sourceEncoding;
447 }
448
449
450
451
452
453
454
455 protected String getOutputEncoding()
456 {
457 return ( outputEncoding != null ) ? outputEncoding : ReaderFactory.UTF_8;
458 }
459
460 static String getPmdVersion()
461 {
462 try
463 {
464 return (String) PMD.class.getField( "VERSION" ).get( null );
465 }
466 catch ( IllegalAccessException e )
467 {
468 throw new RuntimeException( "PMD VERSION field not accessible", e );
469 }
470 catch ( NoSuchFieldException e )
471 {
472 throw new RuntimeException( "PMD VERSION field not found", e );
473 }
474 }
475 }