1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat;
20
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.FilenameFilter;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.io.OutputStreamWriter;
28 import java.io.PrintWriter;
29 import java.net.MalformedURLException;
30 import java.net.URI;
31 import java.net.URL;
32 import java.nio.charset.StandardCharsets;
33 import java.nio.file.Files;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.Objects;
37 import java.util.SortedSet;
38 import java.util.TreeSet;
39 import java.util.function.Consumer;
40
41 import org.apache.commons.io.filefilter.FalseFileFilter;
42 import org.apache.commons.io.filefilter.IOFileFilter;
43 import org.apache.commons.io.function.IOSupplier;
44 import org.apache.rat.config.AddLicenseHeaders;
45 import org.apache.rat.license.ILicense;
46 import org.apache.rat.license.ILicenseFamily;
47 import org.apache.rat.license.LicenseFamilySetFactory;
48 import org.apache.rat.license.LicenseSetFactory;
49 import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
50 import org.apache.rat.report.IReportable;
51 import org.apache.rat.utils.Log;
52 import org.apache.rat.utils.ReportingSet;
53 import org.apache.rat.walker.NameBasedHiddenFileFilter;
54
55
56
57
58
59
60 public class ReportConfiguration {
61 private final ReportingSet<ILicenseFamily> families;
62 private final ReportingSet<ILicense> licenses;
63 private final SortedSet<String> approvedLicenseCategories;
64 private final SortedSet<String> removedLicenseCategories;
65 private boolean addingLicenses;
66 private boolean addingLicensesForced;
67 private String copyrightMessage;
68 private IOSupplier<OutputStream> out;
69 private boolean styleReport;
70 private IOSupplier<InputStream> styleSheet;
71 private IReportable reportable;
72 private FilenameFilter inputFileFilter;
73 private IOFileFilter directoryFilter;
74 private Log log;
75
76
77
78
79
80
81 public ReportConfiguration(Log log) {
82 this.log = log;
83 families = new ReportingSet<>(LicenseFamilySetFactory.emptyLicenseFamilySet()).setLog(log)
84 .setMsgFormat( s -> String.format("Duplicate LicenseFamily category: %s", s.getFamilyCategory()));
85 licenses = new ReportingSet<>(LicenseSetFactory.emptyLicenseSet()).setLog(log)
86 .setMsgFormat( s -> String.format( "Duplicate License %s (%s) of type %s", s.getName(), s.getId(), s.getLicenseFamily().getFamilyCategory()));
87 approvedLicenseCategories = new TreeSet<>();
88 removedLicenseCategories = new TreeSet<>();
89 directoryFilter = NameBasedHiddenFileFilter.HIDDEN;
90 styleReport = true;
91 }
92
93
94
95
96
97 public Log getLog() {
98 return log;
99 }
100
101
102
103
104
105 public void logFamilyCollisions(Log.Level level) {
106 families.setLogLevel(level);
107 }
108
109
110
111
112
113 public void familyDuplicateOption(ReportingSet.Options state) {
114 families.setDuplicateOption(state);
115 }
116
117
118
119
120
121 public void logLicenseCollisions(Log.Level level) {
122 licenses.setLogLevel(level);
123 }
124
125
126
127
128
129 public void licenseDuplicateOption(ReportingSet.Options state) {
130 licenses.setDuplicateOption(state);
131 }
132
133
134
135
136 public FilenameFilter getInputFileFilter() {
137 return inputFileFilter;
138 }
139
140
141
142
143 public void setInputFileFilter(FilenameFilter inputFileFilter) {
144 this.inputFileFilter = inputFileFilter;
145 }
146
147 public IOFileFilter getDirectoryFilter() {
148 return directoryFilter;
149 }
150
151 public void setDirectoryFilter(IOFileFilter directoryFilter) {
152 if (directoryFilter == null) {
153 this.directoryFilter = FalseFileFilter.FALSE;
154 } else {
155 this.directoryFilter = directoryFilter;
156 }
157 }
158
159 public void addDirectoryFilter(IOFileFilter directoryFilter) {
160 this.directoryFilter = this.directoryFilter.and(directoryFilter);
161 }
162
163
164
165
166 public IReportable getReportable() {
167 return reportable;
168 }
169
170
171
172
173 public void setReportable(IReportable reportable) {
174 this.reportable = reportable;
175 }
176
177
178
179
180
181 public IOSupplier<InputStream> getStyleSheet() {
182 return styleSheet;
183 }
184
185
186
187
188
189
190
191
192 public void setStyleSheet(IOSupplier<InputStream> styleSheet) {
193 this.styleSheet = styleSheet;
194 }
195
196
197
198
199
200
201
202
203 public void setFrom(Defaults defaults) {
204 addLicensesIfNotPresent(defaults.getLicenses(LicenseFilter.all));
205 addApprovedLicenseCategories(defaults.getLicenseIds(LicenseFilter.approved));
206 if (isStyleReport() && getStyleSheet() == null) {
207 setStyleSheet(Defaults.getPlainStyleSheet());
208 }
209 }
210
211
212
213
214
215 public void setStyleSheet(File styleSheet) {
216 Objects.requireNonNull(styleSheet, "styleSheet file should not be null");
217 setStyleSheet(styleSheet.toURI());
218 }
219
220
221
222
223
224
225
226 public void setStyleSheet(URI styleSheet) {
227 Objects.requireNonNull(styleSheet, "styleSheet file should not be null");
228 try {
229 setStyleSheet(styleSheet.toURL());
230 } catch (MalformedURLException e) {
231 throw new ConfigurationException("Unable to process stylesheet", e);
232 }
233 }
234
235
236
237
238
239
240
241 public void setStyleSheet(URL styleSheet) {
242 Objects.requireNonNull(styleSheet, "styleSheet file should not be null");
243 setStyleSheet(styleSheet::openStream);
244 }
245
246
247
248
249 public boolean isStyleReport() {
250 return styleReport;
251 }
252
253
254
255
256 public void setStyleReport(boolean styleReport) {
257 this.styleReport = styleReport;
258 }
259
260
261
262
263
264
265
266
267
268
269
270 public void setOut(IOSupplier<OutputStream> out) {
271 this.out = out;
272 }
273
274
275
276
277
278
279
280
281
282 public void setOut(File file) {
283 Objects.requireNonNull(file, "output file should not be null");
284 if (file.exists()) {
285 try {
286 Files.delete(file.toPath());
287 } catch (IOException e) {
288 log.warn("Unable to delete file:"+file);
289 }
290 }
291 setOut(() -> new FileOutputStream(file, true));
292 }
293
294
295
296
297
298
299
300 public IOSupplier<OutputStream> getOutput() {
301 return out == null ? () -> new NoCloseOutputStream(System.out) : out;
302 }
303
304
305
306
307
308 public IOSupplier<PrintWriter> getWriter() {
309 return () -> new PrintWriter(new OutputStreamWriter(getOutput().get(), StandardCharsets.UTF_8));
310 }
311
312
313
314
315
316
317
318 public void addLicense(ILicense license) {
319 if (license != null) {
320 this.licenses.add(license);
321 this.families.addIfNotPresent(license.getLicenseFamily());
322 }
323 }
324
325
326
327
328
329
330
331 public ILicense addLicense(ILicense.Builder builder) {
332 if (builder != null) {
333 ILicense license = builder.build(families);
334 this.licenses.add(license);
335 return license;
336 }
337 return null;
338 }
339
340
341
342
343
344
345
346 public void addLicenses(Collection<ILicense> licenses) {
347 this.licenses.addAll(licenses);
348 licenses.stream().map(ILicense::getLicenseFamily).forEach(families::add);
349 }
350
351
352
353
354
355
356
357 public void addLicensesIfNotPresent(Collection<ILicense> licenses) {
358 this.licenses.addAllIfNotPresent(licenses);
359 licenses.stream().map(ILicense::getLicenseFamily).forEach(families::addIfNotPresent);
360 }
361
362
363
364
365
366
367
368 public void addFamily(ILicenseFamily family) {
369 if (family != null) {
370 this.families.add(family);
371 }
372 }
373
374
375
376
377
378
379
380
381 public void addFamily(ILicenseFamily.Builder builder) {
382 if (builder != null) {
383 this.families.add(builder.build());
384 }
385 }
386
387
388
389
390
391
392
393 public void addFamilies(Collection<ILicenseFamily> families) {
394 this.families.addAll(families);
395 }
396
397
398
399
400
401
402 public void addApprovedLicenseCategory(ILicenseFamily approvedILicenseFamily) {
403 approvedLicenseCategories.add(approvedILicenseFamily.getFamilyCategory());
404 }
405
406
407
408
409
410
411 public void addApprovedLicenseCategory(String familyCategory) {
412 approvedLicenseCategories.add(ILicenseFamily.makeCategory(familyCategory));
413 }
414
415
416
417
418
419
420
421 public void addApprovedLicenseCategories(Collection<String> approvedLicenseCategories) {
422 approvedLicenseCategories.forEach(this::addApprovedLicenseCategory);
423 }
424
425
426
427
428
429
430
431 public void removeApprovedLicenseCategory(String familyCategory) {
432 removedLicenseCategories.add(ILicenseFamily.makeCategory(familyCategory));
433 }
434
435
436
437
438
439
440
441
442 public void removeApprovedLicenseCategories(Collection<String> familyCategory) {
443 familyCategory.forEach(this::removeApprovedLicenseCategory);
444 }
445
446
447
448
449
450
451
452 public SortedSet<String> getApprovedLicenseCategories() {
453 SortedSet<String> result = new TreeSet<>(approvedLicenseCategories);
454 result.removeAll(removedLicenseCategories);
455 return result;
456 }
457
458
459
460
461
462
463
464
465 public String getCopyrightMessage() {
466 return copyrightMessage;
467 }
468
469
470
471
472
473
474
475
476 public void setCopyrightMessage(String copyrightMessage) {
477 this.copyrightMessage = copyrightMessage;
478 }
479
480
481
482
483
484
485
486 public boolean isAddingLicensesForced() {
487 return addingLicensesForced;
488 }
489
490
491
492
493
494
495 public boolean isAddingLicenses() {
496 return addingLicenses;
497 }
498
499
500
501
502
503
504
505
506
507
508 public void setAddLicenseHeaders(AddLicenseHeaders addLicenseHeaders) {
509 addingLicenses = false;
510 addingLicensesForced = false;
511 switch (addLicenseHeaders) {
512 case FALSE:
513
514 break;
515 case FORCED:
516 addingLicensesForced = true;
517
518 case TRUE:
519 addingLicenses = true;
520 break;
521 }
522 }
523
524
525
526
527
528
529
530
531
532
533
534
535 public SortedSet<ILicense> getLicenses(LicenseFilter filter) {
536 switch (filter) {
537 case all:
538 return Collections.unmodifiableSortedSet(licenses);
539 case approved:
540 return new LicenseSetFactory(licenses, getApprovedLicenseCategories()).getLicenses(filter);
541 case none:
542 default:
543 return LicenseSetFactory.emptyLicenseSet();
544 }
545 }
546
547
548
549
550
551
552
553
554
555
556
557
558
559 public SortedSet<ILicenseFamily> getLicenseFamilies(LicenseFilter filter) {
560 return new LicenseFamilySetFactory(families, getApprovedLicenseCategories()).getFamilies(filter);
561 }
562
563
564
565
566
567
568 public void validate(Consumer<String> logger) {
569 if (reportable == null) {
570 throw new ConfigurationException("Reportable may not be null");
571 }
572 if (licenses.isEmpty()) {
573 throw new ConfigurationException("You must specify at least one license");
574 }
575 if (styleSheet != null && !isStyleReport()) {
576 logger.accept("Ignoring stylesheet because styling is not selected");
577 }
578 if (styleSheet == null && isStyleReport()) {
579 throw new ConfigurationException("Stylesheet must be specified if report styling is selected");
580 }
581 }
582
583
584
585
586 public static class NoCloseOutputStream extends OutputStream {
587 private final OutputStream delegate;
588
589 public NoCloseOutputStream(OutputStream delegate) {
590 this.delegate = delegate;
591 }
592
593 @Override
594 public void write(int arg0) throws IOException {
595 delegate.write(arg0);
596 }
597
598 @Override
599 public void close() throws IOException {
600 this.delegate.flush();
601 }
602
603 @Override
604 public boolean equals(Object obj) {
605 return delegate.equals(obj);
606 }
607
608 @Override
609 public void flush() throws IOException {
610 delegate.flush();
611 }
612
613 @Override
614 public int hashCode() {
615 return delegate.hashCode();
616 }
617
618 @Override
619 public String toString() {
620 return delegate.toString();
621 }
622
623 @Override
624 public void write(byte[] arg0, int arg1, int arg2) throws IOException {
625 delegate.write(arg0, arg1, arg2);
626 }
627
628 @Override
629 public void write(byte[] b) throws IOException {
630 delegate.write(b);
631 }
632 }
633 }