1 package org.apache.rat.mp;
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.io.InputStream;
25 import java.io.Writer;
26 import java.lang.reflect.UndeclaredThrowableException;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.List;
31
32 import javax.xml.transform.TransformerConfigurationException;
33
34 import org.apache.maven.plugin.AbstractMojo;
35 import org.apache.maven.plugin.MojoExecutionException;
36 import org.apache.maven.plugin.MojoFailureException;
37 import org.apache.maven.plugins.annotations.Parameter;
38 import org.apache.maven.project.MavenProject;
39 import org.apache.rat.Defaults;
40 import org.apache.rat.Report;
41 import org.apache.rat.ReportConfiguration;
42 import org.apache.rat.analysis.IHeaderMatcher;
43 import org.apache.rat.analysis.util.HeaderMatcherMultiplexer;
44 import org.apache.rat.api.RatException;
45 import org.apache.rat.license.ILicenseFamily;
46 import org.apache.rat.report.IReportable;
47 import org.apache.rat.report.claim.ClaimStatistic;
48 import org.codehaus.plexus.util.DirectoryScanner;
49
50
51
52
53 public abstract class AbstractRatMojo extends AbstractMojo {
54
55
56
57 static final List<String> MAVEN_DEFAULT_EXCLUDES = Collections
58 .unmodifiableList(Arrays.asList("target/**/*",
59 "cobertura.ser",
60 "release.properties",
61 "pom.xml.releaseBackup"));
62
63
64
65
66 static final List<String> ECLIPSE_DEFAULT_EXCLUDES = Collections
67 .unmodifiableList(Arrays.asList(".classpath",
68 ".project",
69 ".settings/**/*"));
70
71
72
73
74 static final List<String> IDEA_DEFAULT_EXCLUDES = Collections
75 .unmodifiableList(Arrays.asList(
76 "*.iml",
77 "*.ipr",
78 "*.iws",
79 ".idea/**/*"));
80
81
82
83
84
85 @Parameter(property = "rat.basedir", defaultValue = "${basedir}", required = true)
86 private File basedir;
87
88
89
90
91
92
93
94 @Deprecated
95 @Parameter
96 private HeaderMatcherSpecification[] licenseMatchers;
97
98
99
100
101
102
103
104
105 @Parameter
106 private IHeaderMatcher[] licenses;
107
108
109
110
111
112
113 @Deprecated
114 private LicenseFamilySpecification[] licenseFamilyNames;
115
116
117
118
119
120
121 @Parameter
122 private ILicenseFamily[] licenseFamilies;
123
124
125
126
127
128 @Parameter(property = "rat.addDefaultLicenseMatchers", defaultValue = "true")
129 private boolean addDefaultLicenseMatchers;
130
131
132
133
134
135
136 @Parameter
137 private String[] includes;
138
139
140
141
142
143
144 @Parameter
145 private String[] excludes;
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 @Parameter(property = "rat.useDefaultExcludes", defaultValue = "true")
161 private boolean useDefaultExcludes;
162
163
164
165
166
167
168
169 @Parameter(property = "rat.useMavenDefaultExcludes", defaultValue = "true")
170 private boolean useMavenDefaultExcludes;
171
172
173
174
175
176
177
178
179 @Parameter(property = "rat.useEclipseDefaultExcludes", defaultValue = "true")
180 private boolean useEclipseDefaultExcludes;
181
182
183
184
185
186
187
188 @Parameter(property = "rat.useIdeaDefaultExcludes", defaultValue = "true")
189 private boolean useIdeaDefaultExcludes;
190
191
192
193
194
195
196 @Parameter(property = "rat.excludeSubprojects", defaultValue = "true")
197 private boolean excludeSubProjects;
198
199
200
201
202 @Parameter(defaultValue = "${project}", required = true, readonly = true)
203 private MavenProject project;
204
205
206
207
208 protected MavenProject getProject() {
209 return project;
210 }
211
212
213
214
215
216
217
218
219
220
221 protected IHeaderMatcher[] getLicenseMatchers()
222 throws MojoFailureException, MojoExecutionException {
223 final List<IHeaderMatcher> list = new ArrayList<IHeaderMatcher>();
224 if (licenses != null) {
225 list.addAll(Arrays.asList(licenses));
226 }
227
228 if (licenseMatchers != null) {
229 for (final HeaderMatcherSpecification spec : licenseMatchers) {
230 final String className = spec.getClassName();
231 final IHeaderMatcher headerMatcher = newInstance(
232 IHeaderMatcher.class, className);
233 list.add(headerMatcher);
234 }
235 }
236
237 if (addDefaultLicenseMatchers) {
238 list.addAll(Arrays.asList(Defaults.DEFAULT_MATCHERS));
239 }
240 return list.toArray(new IHeaderMatcher[list.size()]);
241 }
242
243 private <T> T newInstance(final Class<T> clazz, final String className)
244 throws MojoExecutionException, MojoFailureException {
245 try {
246 final ClassLoader cl = Thread.currentThread()
247 .getContextClassLoader();
248 @SuppressWarnings("unchecked")
249 final T o = (T) cl.loadClass(className).newInstance();
250
251 if (!clazz.isAssignableFrom(o.getClass())) {
252 throw new MojoFailureException("The class "
253 + o.getClass().getName() + " does not implement "
254 + clazz.getName());
255 }
256 return o;
257 } catch (InstantiationException e) {
258 throw new MojoExecutionException("Failed to instantiate class "
259 + className + ": " + e.getMessage(), e);
260 } catch (ClassCastException e) {
261 throw new MojoExecutionException("The class " + className
262 + " is not implementing " + clazz.getName() + ": "
263 + e.getMessage(), e);
264 } catch (IllegalAccessException e) {
265 throw new MojoExecutionException("Illegal access to class "
266 + className + ": " + e.getMessage(), e);
267 } catch (ClassNotFoundException e) {
268 throw new MojoExecutionException("Class " + className
269 + " not found: " + e.getMessage(), e);
270 }
271 }
272
273
274
275
276
277
278
279
280
281 private static void add(List<String> pList, String[] pArray) {
282 if (pArray != null) {
283 Collections.addAll(pList, pArray);
284 }
285 }
286
287
288
289
290
291
292 protected IReportable getResources() {
293 final DirectoryScanner ds = new DirectoryScanner();
294 ds.setBasedir(basedir);
295 setExcludes(ds);
296 setIncludes(ds);
297 ds.scan();
298 whenDebuggingLogExcludedFiles(ds);
299 final String[] files = ds.getIncludedFiles();
300 logAboutIncludedFiles(files);
301 try {
302 return new FilesReportable(basedir, files);
303 } catch (IOException e) {
304 throw new UndeclaredThrowableException(e);
305 }
306 }
307
308 private void logAboutIncludedFiles(final String[] files) {
309 if (files.length == 0) {
310 getLog().warn("No resources included.");
311 } else {
312 getLog().info(
313 files.length
314 + " resources included (use -debug for more details)");
315 if (getLog().isDebugEnabled()) {
316 for (String resource : files) {
317 getLog().debug(" - included " + resource);
318 }
319 }
320 }
321 }
322
323 private void whenDebuggingLogExcludedFiles(final DirectoryScanner ds) {
324 if (getLog().isDebugEnabled()) {
325 final String[] excludedFiles = ds.getExcludedFiles();
326 if (excludedFiles.length == 0) {
327 getLog().debug("No excluded resources.");
328 } else {
329 getLog().debug(
330 "Excluded " + excludedFiles.length + " resources:");
331 for (final String resource : excludedFiles) {
332 getLog().debug(" - excluded " + resource);
333 }
334 }
335 }
336 }
337
338 private void setIncludes(DirectoryScanner ds) {
339 if (includes != null) {
340 ds.setIncludes(includes);
341 }
342 }
343
344 private void setExcludes(DirectoryScanner ds) {
345 final List<String> excludeList = buildDefaultExclusions();
346 if (excludes == null || excludes.length == 0) {
347 getLog().info("No excludes explicitly specified.");
348 } else {
349 for (String exclude : excludes) {
350 getLog().info("Exclude: " + exclude);
351 }
352 }
353 add(excludeList, excludes);
354 if (!excludeList.isEmpty()) {
355 String[] allExcludes = excludeList.toArray(new String[excludeList
356 .size()]);
357 ds.setExcludes(allExcludes);
358 }
359 }
360
361 private List<String> buildDefaultExclusions() {
362 final List<String> results = new ArrayList<String>();
363
364 addPlexusDefaults(results);
365
366 addMavenDefaults(results);
367
368 addEclipseDefaults(results);
369
370 addIdeaDefaults(results);
371
372 if (excludeSubProjects && project != null
373 && project.getModules() != null) {
374 for (Object o : project.getModules()) {
375 String moduleSubPath = (String) o;
376 results.add(moduleSubPath + "/**/*");
377 }
378 }
379
380 getLog().debug("Finished creating list of implicit excludes.");
381 if (results.isEmpty()) {
382 getLog().info("No excludes implicitly specified.");
383 } else {
384 getLog().info(
385 results.size()
386 + " implicit excludes (use -debug for more details).");
387 for (final String exclude : results) {
388 getLog().debug("Implicit exclude: " + exclude);
389 }
390 }
391
392 return results;
393 }
394
395 private void addPlexusDefaults(final List<String> excludeList1) {
396 if (useDefaultExcludes) {
397 getLog().debug("Adding plexus default exclusions...");
398 Collections.addAll(excludeList1, DirectoryScanner.DEFAULTEXCLUDES);
399 } else {
400 getLog().debug(
401 "rat.useDefaultExcludes set to false. "
402 + "Plexus default exclusions will not be added");
403 }
404 }
405
406 private void addMavenDefaults(final List<String> excludeList1) {
407 if (useMavenDefaultExcludes) {
408 getLog().debug(
409 "Adding exclusions often needed by Maven projects...");
410 excludeList1.addAll(MAVEN_DEFAULT_EXCLUDES);
411 } else {
412 getLog().debug(
413 "rat.useMavenDefaultExcludes set to false. "
414 + "Exclusions often needed by Maven projects will not be added.");
415 }
416 }
417
418 private void addEclipseDefaults(final List<String> excludeList1) {
419 if (useEclipseDefaultExcludes) {
420 getLog().debug(
421 "Adding exclusions often needed by projects "
422 + "developed in Eclipse...");
423 excludeList1.addAll(ECLIPSE_DEFAULT_EXCLUDES);
424 } else {
425 getLog().debug(
426 "rat.useEclipseDefaultExcludes set to false. "
427 + "Exclusions often needed by projects developed in "
428 + "Eclipse will not be added.");
429 }
430 }
431
432 private void addIdeaDefaults(final List<String> excludeList1) {
433 if (useIdeaDefaultExcludes) {
434 getLog().debug(
435 "Adding exclusions often needed by projects "
436 + "developed in IDEA...");
437 excludeList1.addAll(IDEA_DEFAULT_EXCLUDES);
438 } else {
439 getLog().debug(
440 "rat.useIdeaDefaultExcludes set to false. "
441 + "Exclusions often needed by projects developed in "
442 + "IDEA will not be added.");
443 }
444 }
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 protected ClaimStatistic createReport(Writer out, InputStream style)
462 throws MojoExecutionException, MojoFailureException {
463 final ReportConfiguration configuration = getConfiguration();
464 try {
465 if (style != null) {
466 return Report.report(out, getResources(), style, configuration);
467 } else {
468 return Report.report(getResources(), out, configuration);
469 }
470 } catch (TransformerConfigurationException e) {
471 throw new MojoExecutionException(e.getMessage(), e);
472 } catch (IOException e) {
473 throw new MojoExecutionException(e.getMessage(), e);
474 } catch (InterruptedException e) {
475 throw new MojoExecutionException(e.getMessage(), e);
476 } catch (RatException e) {
477 throw new MojoExecutionException(e.getMessage(), e);
478 }
479 }
480
481 protected ReportConfiguration getConfiguration()
482 throws MojoFailureException, MojoExecutionException {
483 final ReportConfiguration configuration = new ReportConfiguration();
484 configuration.setHeaderMatcher(new HeaderMatcherMultiplexer(
485 getLicenseMatchers()));
486 configuration.setApprovedLicenseNames(getApprovedLicenseNames());
487 return configuration;
488 }
489
490 private ILicenseFamily[] getApprovedLicenseNames()
491 throws MojoExecutionException, MojoFailureException {
492 final List<ILicenseFamily> list = new ArrayList<ILicenseFamily>();
493 if (licenseFamilies != null) {
494 list.addAll(Arrays.asList(licenseFamilies));
495 }
496 if (licenseFamilyNames != null) {
497 for (LicenseFamilySpecification spec : licenseFamilyNames) {
498 list.add(newInstance(ILicenseFamily.class, spec.getClassName()));
499 }
500 }
501
502 if (list.isEmpty()) {
503 return null;
504 }
505 return list.toArray(new ILicenseFamily[list.size()]);
506 }
507 }