1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.mp;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.PrintWriter;
24 import java.net.MalformedURLException;
25 import java.net.URI;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Objects;
32 import java.util.SortedSet;
33 import java.util.function.Consumer;
34 import java.util.stream.Collectors;
35 import java.util.stream.Stream;
36
37 import org.apache.commons.cli.Option;
38 import org.apache.commons.lang3.StringUtils;
39 import org.apache.maven.plugin.MojoExecutionException;
40 import org.apache.maven.plugins.annotations.Parameter;
41 import org.apache.maven.project.MavenProject;
42 import org.apache.rat.ConfigurationException;
43 import org.apache.rat.Defaults;
44 import org.apache.rat.OptionCollection;
45 import org.apache.rat.ReportConfiguration;
46 import org.apache.rat.analysis.license.DeprecatedConfig;
47 import org.apache.rat.commandline.Arg;
48 import org.apache.rat.config.exclusion.StandardCollection;
49 import org.apache.rat.configuration.Format;
50 import org.apache.rat.configuration.LicenseReader;
51 import org.apache.rat.configuration.MatcherReader;
52 import org.apache.rat.document.DocumentName;
53 import org.apache.rat.document.FileDocument;
54 import org.apache.rat.license.ILicense;
55 import org.apache.rat.license.ILicenseFamily;
56 import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
57 import org.apache.rat.license.SimpleLicenseFamily;
58 import org.apache.rat.plugin.BaseRatMojo;
59 import org.apache.rat.utils.DefaultLog;
60 import org.apache.rat.utils.Log;
61 import org.apache.rat.walker.DirectoryWalker;
62
63 import static java.lang.String.format;
64
65
66
67
68 public abstract class AbstractRatMojo extends BaseRatMojo {
69
70 private ReportConfiguration reportConfiguration;
71
72
73
74 @Parameter(property = "rat.basedir", defaultValue = "${basedir}", required = true)
75 private File basedir;
76
77
78
79
80
81
82
83
84 @Parameter
85 @Deprecated
86 private String[] defaultLicenseFiles;
87
88
89
90
91
92 @Parameter
93 @Deprecated
94 private String[] additionalLicenseFiles;
95
96
97
98
99
100 @Deprecated
101 @Parameter(property = "rat.addDefaultLicenses", name = "addDefaultLicenses")
102 public void setAddDefaultLicenses(final boolean addDefaultLicenses) {
103 setNoDefaultLicenses(!addDefaultLicenses);
104 }
105
106
107
108
109
110 @Deprecated
111 @Parameter(property = "rat.addDefaultLicenseMatchers")
112 private boolean addDefaultLicenseMatchers;
113
114
115
116
117 @Deprecated
118 @Parameter
119 private String[] approvedLicenses;
120
121
122
123
124 @Deprecated
125 @Parameter(property = "rat.approvedFile")
126 private String approvedLicenseFile;
127
128
129
130
131
132
133
134 @Deprecated
135 @Parameter
136 private SimpleLicenseFamily[] licenseFamilies;
137
138
139
140
141 @Deprecated
142 @Parameter
143 private Object[] licenses;
144
145
146
147
148 @Deprecated
149 @Parameter
150 private Family[] families;
151
152
153
154
155
156 @Parameter(property = "rat.includesFileCharset", defaultValue = "${project.build.sourceEncoding}")
157 private String includesFileCharset;
158
159
160
161
162
163 @Parameter(property = "rat.excludesFileCharset", defaultValue = "${project.build.sourceEncoding}")
164 private String excludesFileCharset;
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 @Parameter(property = "rat.useDefaultExcludes", defaultValue = "true")
184 @Deprecated
185 private boolean useDefaultExcludes;
186
187
188
189
190
191
192
193
194
195 @Parameter(property = "rat.useMavenDefaultExcludes", defaultValue = "true")
196 @Deprecated
197 private boolean useMavenDefaultExcludes;
198
199
200
201
202
203
204
205
206
207
208 @Parameter(property = "rat.parseSCMIgnoresAsExcludes", defaultValue = "true")
209 @Deprecated
210 private boolean parseSCMIgnoresAsExcludes;
211
212
213
214
215
216
217
218
219
220 @Parameter(property = "rat.useEclipseDefaultExcludes", defaultValue = "true")
221 @Deprecated
222 private boolean useEclipseDefaultExcludes;
223
224
225
226
227
228
229
230
231
232 @Deprecated
233 @Parameter(property = "rat.useIdeaDefaultExcludes", defaultValue = "true")
234 private boolean useIdeaDefaultExcludes;
235
236
237
238
239
240 @Parameter(property = "rat.excludeSubprojects", defaultValue = "true")
241 private boolean excludeSubProjects;
242
243
244
245
246
247
248
249 @Parameter(property = "rat.skip", defaultValue = "false")
250 protected boolean skip;
251
252
253
254
255
256 @Parameter(defaultValue = "${project}", required = true, readonly = true)
257 protected MavenProject project;
258
259 protected AbstractRatMojo() {
260 DefaultLog.setInstance(makeLog());
261 }
262
263
264
265
266 protected MavenProject getProject() {
267 return project;
268 }
269
270 protected Defaults.Builder getDefaultsBuilder() {
271 Defaults.Builder result = Defaults.builder();
272 if (defaultLicenseFiles != null) {
273 for (String defaultLicenseFile : defaultLicenseFiles) {
274 try {
275 result.add(defaultLicenseFile);
276 } catch (MalformedURLException e) {
277 throw new ConfigurationException(defaultLicenseFile + " is not a valid license file", e);
278 }
279 }
280 }
281 return result;
282 }
283
284 @Deprecated
285 private Stream<License> getLicenses() {
286 if (licenses == null) {
287 return Stream.empty();
288 }
289 return Arrays.stream(licenses).filter(s -> s instanceof License).map(License.class::cast);
290 }
291
292 @Deprecated
293 private Stream<DeprecatedConfig> getDeprecatedConfigs() {
294 if (licenses == null) {
295 return Stream.empty();
296 }
297 return Arrays.stream(licenses).filter(s -> s instanceof DeprecatedConfig).map(DeprecatedConfig.class::cast);
298 }
299
300 @Deprecated
301 private void reportDeprecatedProcessing() {
302 if (getDeprecatedConfigs().findAny().isPresent()) {
303 DefaultLog.getInstance().warn("Configuration uses deprecated configuration. You need to upgrade to v0.17 configuration options.");
304 }
305 }
306
307 @Deprecated
308 private void processLicenseFamilies(final ReportConfiguration config) {
309 List<ILicenseFamily> families = getDeprecatedConfigs().map(DeprecatedConfig::getLicenseFamily).filter(Objects::nonNull).collect(Collectors.toList());
310 if (licenseFamilies != null) {
311 for (SimpleLicenseFamily slf : licenseFamilies) {
312 if (StringUtils.isBlank(slf.getFamilyCategory())) {
313 families.stream().filter(f -> f.getFamilyName().equalsIgnoreCase(slf.getFamilyName())).findFirst()
314 .ifPresent(config::addApprovedLicenseCategory);
315 } else {
316 config.addApprovedLicenseCategory(ILicenseFamily.builder().setLicenseFamilyCategory(slf.getFamilyCategory())
317 .setLicenseFamilyName(StringUtils.defaultIfBlank(slf.getFamilyName(), slf.getFamilyCategory()))
318 .build());
319 }
320 }
321 }
322 }
323
324
325
326
327
328
329
330 protected List<String> getValues(final Arg arg) {
331 List<String> result = new ArrayList<>();
332 for (Option option : arg.group().getOptions()) {
333 if (option.getLongOpt() != null) {
334 List<String> args = getArg(option.getLongOpt());
335 if (args != null) {
336 result.addAll(args);
337 }
338 }
339 }
340 return result;
341 }
342
343
344
345
346
347 protected void removeKey(final Arg arg) {
348 for (Option option : arg.group().getOptions()) {
349 if (option.getLongOpt() != null) {
350 removeArg(option.getLongOpt());
351 }
352 }
353 }
354
355 private org.apache.rat.utils.Log makeLog() {
356 return new org.apache.rat.utils.Log() {
357 @Override
358 public Level getLevel() {
359 final org.apache.maven.plugin.logging.Log log = getLog();
360 if (log.isDebugEnabled()) {
361 return Level.DEBUG;
362 }
363 if (log.isInfoEnabled()) {
364 return Level.INFO;
365 }
366 if (log.isWarnEnabled()) {
367 return Level.WARN;
368 }
369 if (log.isErrorEnabled()) {
370 return Level.ERROR;
371 }
372 return Level.OFF;
373 }
374
375 @Override
376 public void log(final Level level, final String message, final Throwable throwable) {
377 final org.apache.maven.plugin.logging.Log log = getLog();
378 switch (level) {
379 case DEBUG:
380 if (throwable != null) {
381 log.debug(message, throwable);
382 } else {
383 log.debug(message);
384 }
385 break;
386 case INFO:
387 if (throwable != null) {
388 log.info(message, throwable);
389 } else {
390 log.info(message);
391 }
392 break;
393 case WARN:
394 if (throwable != null) {
395 log.warn(message, throwable);
396 } else {
397 log.warn(message);
398 }
399 break;
400 case ERROR:
401 if (throwable != null) {
402 log.error(message, throwable);
403 } else {
404 log.error(message);
405 }
406 break;
407 case OFF:
408 break;
409 }
410 }
411
412 @Override
413 public void log(final Level level, final String msg) {
414 final org.apache.maven.plugin.logging.Log log = getLog();
415 switch (level) {
416 case DEBUG:
417 log.debug(msg);
418 break;
419 case INFO:
420 log.info(msg);
421 break;
422 case WARN:
423 log.warn(msg);
424 break;
425 case ERROR:
426 log.error(msg);
427 break;
428 case OFF:
429 break;
430 }
431 }
432 };
433 }
434
435 private void setIncludeExclude() {
436
437 if (excludeSubProjects && project != null && project.getModules() != null) {
438 List<String> subModules = new ArrayList<>();
439 project.getModules().forEach(s -> subModules.add(format("%s/**", s)));
440 setInputExcludes(subModules.toArray(new String[0]));
441 }
442
443 List<String> values = getValues(Arg.EXCLUDE);
444 if (values.isEmpty() && useDefaultExcludes) {
445 DefaultLog.getInstance().debug("Adding plexus default exclusions...");
446 setInputExcludes(StandardCollection.STANDARD_PATTERNS.patterns().toArray(new String[0]));
447
448 DefaultLog.getInstance().debug("Adding SCM default exclusions...");
449 setInputExcludes(StandardCollection.STANDARD_SCMS.patterns().toArray(new String[0]));
450 }
451
452 if (useMavenDefaultExcludes) {
453 setInputExcludeStd(StandardCollection.MAVEN.name());
454 }
455 if (useEclipseDefaultExcludes) {
456 setInputExcludeStd(StandardCollection.ECLIPSE.name());
457 }
458 if (useIdeaDefaultExcludes) {
459 setInputExcludeStd(StandardCollection.IDEA.name());
460 }
461
462 if (parseSCMIgnoresAsExcludes) {
463 setInputExcludeParsedScm(StandardCollection.STANDARD_SCMS.name());
464 }
465 }
466
467 protected ReportConfiguration getConfiguration() throws MojoExecutionException {
468 Log log = DefaultLog.getInstance();
469 if (reportConfiguration == null) {
470 try {
471 if (super.getLog().isDebugEnabled()) {
472 log.debug("Start BaseRatMojo Configuration options");
473 for (Map.Entry<String, List<String>> entry : args.entrySet()) {
474 log.debug(format(" * %s %s", entry.getKey(), String.join(", ", entry.getValue())));
475 }
476 log.debug("End BaseRatMojo Configuration options");
477 }
478
479 boolean helpLicenses = !getValues(Arg.HELP_LICENSES).isEmpty();
480 removeKey(Arg.HELP_LICENSES);
481
482 setIncludeExclude();
483
484 getLog().warn("Basedir is : " + basedir);
485 ReportConfiguration config = OptionCollection.parseCommands(basedir, args().toArray(new String[0]),
486 o -> getLog().warn("Help option not supported"),
487 true);
488 reportDeprecatedProcessing();
489
490 if (additionalLicenseFiles != null) {
491 for (String licenseFile : additionalLicenseFiles) {
492 URI uri = new File(licenseFile).toURI();
493 Format fmt = Format.from(licenseFile);
494 MatcherReader mReader = fmt.matcherReader();
495 if (mReader != null) {
496 mReader.addMatchers(uri);
497 }
498 LicenseReader lReader = fmt.licenseReader();
499 if (lReader != null) {
500 lReader.addLicenses(uri);
501 config.addLicenses(lReader.readLicenses());
502 config.addApprovedLicenseCategories(lReader.approvedLicenseId());
503 }
504 }
505 }
506 if (families != null || getDeprecatedConfigs().findAny().isPresent()) {
507 if (log.isEnabled(Log.Level.DEBUG)) {
508 log.debug(format("%s license families loaded from pom", families.length));
509 }
510 Consumer<ILicenseFamily> logger = super.getLog().isDebugEnabled() ? l -> log.debug(format("Family: %s", l))
511 : l -> {
512 };
513
514 Consumer<ILicenseFamily> process = logger.andThen(config::addFamily);
515 getDeprecatedConfigs().map(DeprecatedConfig::getLicenseFamily).filter(Objects::nonNull).forEach(process);
516 if (families != null) {
517 Arrays.stream(families).map(Family::build).forEach(process);
518 }
519 }
520
521 processLicenseFamilies(config);
522
523 if (approvedLicenses != null && approvedLicenses.length > 0) {
524 Arrays.stream(approvedLicenses).forEach(config::addApprovedLicenseCategory);
525 }
526
527 if (licenses != null) {
528 if (log.isEnabled(Log.Level.DEBUG)) {
529 log.debug(format("%s licenses loaded from pom", licenses.length));
530 }
531 Consumer<ILicense> logger = log.isEnabled(Log.Level.DEBUG) ? l -> log.debug(format("License: %s", l))
532 : l -> {
533 };
534 Consumer<ILicense> addApproved = (approvedLicenses == null || approvedLicenses.length == 0)
535 ? l -> config.addApprovedLicenseCategory(l.getLicenseFamily())
536 : l -> {
537 };
538
539 Consumer<ILicense> process = logger.andThen(config::addLicense).andThen(addApproved);
540 SortedSet<ILicenseFamily> families = config.getLicenseFamilies(LicenseFilter.ALL);
541 getDeprecatedConfigs().map(DeprecatedConfig::getLicense).filter(Objects::nonNull)
542 .map(x -> x.setLicenseFamilies(families).build()).forEach(process);
543 getLicenses().map(x -> x.build(families)).forEach(process);
544 }
545 DocumentName dirName = DocumentName.builder(basedir).build();
546 config.addSource(new DirectoryWalker(new FileDocument(dirName, basedir, config.getDocumentExcluder(dirName))));
547
548 if (helpLicenses) {
549 new org.apache.rat.help.Licenses(config, new PrintWriter(log.asWriter())).printHelp();
550 }
551 reportConfiguration = config;
552 } catch (IOException e) {
553 throw new MojoExecutionException(e);
554 }
555 }
556 return reportConfiguration;
557 }
558
559 protected void logLicenses(final Collection<ILicense> licenses) {
560 if (getLog().isDebugEnabled()) {
561 getLog().debug("The following " + licenses.size() + " licenses are activated:");
562 for (ILicense license : licenses) {
563 getLog().debug("* " + license.toString());
564 }
565 }
566 }
567 }