1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 */
19 package org.apache.rat;
20
21 import java.io.File;
22 import java.io.FileFilter;
23 import java.io.FileOutputStream;
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.ArrayList;
35 import java.util.Collection;
36 import java.util.List;
37 import java.util.Objects;
38 import java.util.SortedSet;
39 import java.util.function.Consumer;
40
41 import org.apache.commons.io.function.IOSupplier;
42 import org.apache.rat.analysis.IHeaderMatcher;
43 import org.apache.rat.commandline.StyleSheets;
44 import org.apache.rat.config.AddLicenseHeaders;
45 import org.apache.rat.config.exclusion.ExclusionProcessor;
46 import org.apache.rat.config.exclusion.StandardCollection;
47 import org.apache.rat.config.results.ClaimValidator;
48 import org.apache.rat.configuration.builders.AnyBuilder;
49 import org.apache.rat.document.DocumentName;
50 import org.apache.rat.document.DocumentNameMatcher;
51 import org.apache.rat.document.FileDocument;
52 import org.apache.rat.license.ILicense;
53 import org.apache.rat.license.ILicenseFamily;
54 import org.apache.rat.license.LicenseSetFactory;
55 import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
56 import org.apache.rat.report.IReportable;
57 import org.apache.rat.utils.DefaultLog;
58 import org.apache.rat.utils.Log.Level;
59 import org.apache.rat.utils.ReportingSet;
60 import org.apache.rat.walker.FileListWalker;
61 import org.apache.rat.walker.IReportableListWalker;
62
63 /**
64 * A configuration object is used by the front end to invoke the
65 * {@link Reporter}. The sole purpose of the frontends is to create the
66 * configuration and invoke the {@link Reporter}.
67 */
68 public class ReportConfiguration {
69
70 /**
71 * The styles of processing for various categories of documents.
72 */
73 public enum Processing {
74 /** List file as present only */
75 NOTIFICATION("List file as present"),
76 /** List all present licenses */
77 PRESENCE("List any licenses found"),
78 /** List all present licenses and unknown licenses */
79 ABSENCE("List licenses found and any unknown licences");
80
81 /**
82 * Description of the processing
83 */
84 private final String description;
85
86
87 Processing(final String description) {
88 this.description = description;
89 }
90
91 /**
92 * Gets the description of the processing type.
93 * @return the description of the processing type.
94 */
95 public String desc() {
96 return description;
97 }
98 }
99
100 /** The LicenseSetFactory for the configuration */
101 private final LicenseSetFactory licenseSetFactory;
102
103 /**
104 * {@code true} if we are adding license headers to the files.
105 */
106 private boolean addingLicenses;
107 /**
108 * {@code true} if we are adding license headers in place (no *.new files)
109 */
110 private boolean addingLicensesForced;
111 /**
112 * The copyright message to add if we are adding headers. Will be null if we are not
113 * adding copyright messages.
114 */
115 private String copyrightMessage;
116 /**
117 * The IOSupplier that provides the output stream to write the report to.
118 */
119 private IOSupplier<OutputStream> out;
120 /**
121 * The IOSupplier that provides the stylesheet to style the XML output.
122 */
123 private IOSupplier<InputStream> styleSheet;
124
125 /**
126 * A list of files to read file names from.
127 */
128 private final List<File> sources;
129
130 /**
131 * A list of reportables to process;
132 */
133 private final List<IReportable> reportables;
134
135 /**
136 * A predicate to test if a path should be included in the processing.
137 */
138 private final ExclusionProcessor exclusionProcessor;
139
140 /**
141 * The default filter for displaying families.
142 */
143 private LicenseFilter listFamilies;
144 /**
145 * The default filter for displaying licenses.
146 */
147 private LicenseFilter listLicenses;
148 /**
149 * {@code true} if this is a dry run and no processing is to take place.
150 */
151 private boolean dryRun;
152 /**
153 * How to process ARCHIVE document types.
154 */
155 private Processing archiveProcessing;
156 /**
157 * How to process STANDARD document types.
158 */
159 private Processing standardProcessing;
160 /**
161 * The ClaimValidator to validate min/max counts and similar claims.
162 */
163 private final ClaimValidator claimValidator;
164 /**
165 * Constructor
166 */
167 public ReportConfiguration() {
168 licenseSetFactory = new LicenseSetFactory();
169 listFamilies = Defaults.LIST_FAMILIES;
170 listLicenses = Defaults.LIST_LICENSES;
171 dryRun = false;
172 exclusionProcessor = new ExclusionProcessor();
173 claimValidator = new ClaimValidator();
174 sources = new ArrayList<>();
175 reportables = new ArrayList<>();
176 }
177
178 /**
179 * Report the excluded files to the appendable object.
180 * @param appendable the appendable object to write to.
181 */
182 public void reportExclusions(final Appendable appendable) {
183 try {
184 exclusionProcessor.reportExclusions(appendable);
185 } catch (IOException e) {
186 DefaultLog.getInstance().warn("Unable to report exclusions", e);
187 }
188 }
189
190 /**
191 * Adds a file as a source of files to scan.
192 * The file must be a text file that lists files to be included.
193 * File within the file must be in linux format with a
194 * "/" file separator.
195 * @param file the file to process.
196 */
197 public void addSource(final File file) {
198 notNull(file, "File may not be null.");
199 sources.add(file);
200 }
201
202 private void notNull(final Object o, final String msg) {
203 if (o == null) {
204 throw new ConfigurationException(msg);
205 }
206 }
207
208 /**
209 * Adds a Reportable as a source of files to scan.
210 * @param reportable the reportable to process.
211 */
212 public void addSource(final IReportable reportable) {
213 notNull(reportable, "Reportable may not be null.");
214 reportables.add(reportable);
215 }
216
217 /**
218 * Returns {@code true} if the configuration has any sources defined.
219 * @return {@code true} if the configuration has any sources defined.
220 */
221 public boolean hasSource() {
222 return !reportables.isEmpty() || !sources.isEmpty();
223 }
224
225 /**
226 * Gets a builder initialized with any files specified as sources.
227 * @return a configured builder.
228 */
229 public IReportableListWalker.Builder getSources() {
230 DocumentName name = DocumentName.builder(new File(".")).build();
231 IReportableListWalker.Builder builder = IReportableListWalker.builder(name);
232 sources.forEach(file -> builder.addReportable(new FileListWalker(new FileDocument(file, DocumentNameMatcher.MATCHES_ALL))));
233 reportables.forEach(builder::addReportable);
234 return builder;
235 }
236
237 /**
238 * Gets the matcher that matches generated text.
239 * @return the matcher that matches generated text.
240 */
241 public IHeaderMatcher getGeneratedMatcher() {
242 return new AnyBuilder().setResource("/org/apache/rat/generation-keywords.txt").build();
243 }
244
245 /**
246 * Retrieves the archive processing type.
247 * @return The archive processing type.
248 */
249 public Processing getArchiveProcessing() {
250 return archiveProcessing == null ? Defaults.ARCHIVE_PROCESSING : archiveProcessing;
251 }
252
253 /**
254 * Sets the archive processing type. If not set will default to NOTIFICATION.
255 * @param archiveProcessing the type of processing archives should have.
256 */
257 public void setArchiveProcessing(final Processing archiveProcessing) {
258 this.archiveProcessing = archiveProcessing;
259 }
260
261 /**
262 * Retrieves the archive processing type.
263 * @return The archive processing type.
264 */
265 public Processing getStandardProcessing() {
266 return standardProcessing == null ? Defaults.STANDARD_PROCESSING : standardProcessing;
267 }
268
269 /**
270 * Sets the archive processing type. If not set will default to NOTIFICATION.
271 * @param standardProcessing the type of processing archives should have.
272 */
273 public void setStandardProcessing(final Processing standardProcessing) {
274 this.standardProcessing = standardProcessing;
275 }
276
277 /**
278 * Set the log level for reporting collisions in the set of license families.
279 * <p>NOTE: should be set before licenses or license families are added.</p>
280 * @param level The log level to use.
281 */
282 public void logFamilyCollisions(final Level level) {
283 licenseSetFactory.logFamilyCollisions(level);
284 }
285
286 /**
287 * Sets the reporting option for duplicate license families.
288 * @param state The ReportingSet.Option to use for reporting.
289 */
290 public void familyDuplicateOption(final ReportingSet.Options state) {
291 licenseSetFactory.familyDuplicateOption(state);
292 }
293
294 /**
295 * Sets the log level for reporting license collisions.
296 * @param level The log level.
297 */
298 public void logLicenseCollisions(final Level level) {
299 licenseSetFactory.logLicenseCollisions(level);
300 }
301
302 /**
303 * Sets the reporting option for duplicate licenses.
304 * @param state the ReportingSt.Option to use for reporting.
305 */
306 public void licenseDuplicateOption(final ReportingSet.Options state) {
307 licenseSetFactory.licenseDuplicateOption(state);
308 }
309
310 /**
311 * Set the level of license families that should be output in the XML document.
312 * @param filter the license families to list.
313 */
314 public void listFamilies(final LicenseFilter filter) {
315 listFamilies = filter;
316 }
317
318 /**
319 * Return the current filter that determines which families will be output in the XML document.
320 * @return the filter that defines the families to list.
321 */
322 public LicenseFilter listFamilies() {
323 return listFamilies;
324 }
325
326 /**
327 * Set the level of licenses that should be output in the XML document.
328 * @param filter the licenses to list.
329 */
330 public void listLicenses(final LicenseFilter filter) {
331 listLicenses = filter;
332 }
333
334 /**
335 * Gets the selected license filter.
336 * @return the filter to limit license display.
337 */
338 public LicenseFilter listLicenses() {
339 return listLicenses;
340 }
341
342 /**
343 * Sets the dry run flag.
344 * @param state the state for the dry run flag.
345 */
346 public void setDryRun(final boolean state) {
347 dryRun = state;
348 }
349
350 /**
351 * Returns the state of the dry run flag.
352 * @return the state of the dry run flag.
353 */
354 public boolean isDryRun() {
355 return dryRun;
356 }
357
358 /**
359 * Excludes a StandardCollection of patterns.
360 * @param collection the StandardCollection to exclude.
361 * @see ExclusionProcessor#addExcludedCollection(StandardCollection)
362 */
363 public void addExcludedCollection(final StandardCollection collection) {
364 exclusionProcessor.addExcludedCollection(collection);
365 }
366
367 /**
368 * Excludes the file processor defined in the StandardCollection.
369 * @param collection the StandardCollection to exclude.
370 * @see ExclusionProcessor#addFileProcessor(StandardCollection)
371 */
372 public void addExcludedFileProcessor(final StandardCollection collection) {
373 exclusionProcessor.addFileProcessor(collection);
374 }
375
376 /**
377 * Excludes files that match a FileFilter.
378 * @param fileFilter the file filter to match.
379 */
380 public void addExcludedFilter(final FileFilter fileFilter) {
381 exclusionProcessor.addExcludedMatcher(new DocumentNameMatcher(fileFilter));
382 }
383
384 /**
385 * Excludes files that match a DocumentNameMatcher.
386 * @param matcher the DocumentNameMatcher to match.
387 */
388 public void addExcludedMatcher(final DocumentNameMatcher matcher) {
389 exclusionProcessor.addExcludedMatcher(matcher);
390 }
391
392 /**
393 * Excludes files that match the pattern.
394 *
395 * @param patterns the collection of patterns to exclude.
396 * @see ExclusionProcessor#addIncludedPatterns(Iterable)
397 */
398 public void addExcludedPatterns(final Iterable<String> patterns) {
399 exclusionProcessor.addExcludedPatterns(patterns);
400 }
401
402 /**
403 * Adds the patterns from the standard collection as included patterns.
404 * @param collection the standard collection to include.
405 */
406 public void addIncludedCollection(final StandardCollection collection) {
407 exclusionProcessor.addIncludedCollection(collection);
408 }
409
410 /**
411 * Adds the fileFilter to filter files that should be included, this overrides any
412 * exclusion of the same files.
413 * @param fileFilter the filter to identify files that should be included.
414 */
415 public void addIncludedFilter(final FileFilter fileFilter) {
416 exclusionProcessor.addIncludedMatcher(new DocumentNameMatcher(fileFilter));
417 }
418
419 /**
420 * Add file patterns that are to be included. These patterns override any exclusion of
421 * the same files.
422 * @param patterns The iterable of Strings containing the patterns.
423 */
424 public void addIncludedPatterns(final Iterable<String> patterns) {
425 exclusionProcessor.addIncludedPatterns(patterns);
426 }
427
428 /**
429 * Get the DocumentNameMatcher that excludes files found in the directory tree..
430 * @param baseDir the DocumentName for the base directory.
431 * @return the DocumentNameMatcher for the base directory.
432 */
433 public DocumentNameMatcher getDocumentExcluder(final DocumentName baseDir) {
434 return exclusionProcessor.getNameMatcher(baseDir);
435 }
436
437 /**
438 * Gets the IOSupplier with the style sheet.
439 * @return the Supplier of the InputStream that is the XSLT style sheet to style
440 * the report with.
441 */
442 public IOSupplier<InputStream> getStyleSheet() {
443 return styleSheet;
444 }
445
446 /**
447 * Sets the style sheet for custom processing. The IOSupplier may be called
448 * multiple times, so the input stream must be able to be opened and closed
449 * multiple times.
450 * @param styleSheet the XSLT style sheet to style the report with.
451 */
452 public void setStyleSheet(final IOSupplier<InputStream> styleSheet) {
453 this.styleSheet = styleSheet;
454 }
455
456 /**
457 * Adds the licenses and approved licenses from the defaults object to the
458 * configuration. <em>Side effect:</em> if the report should be styled and no
459 * style sheet has been set the plain stylesheet from the defaults will be used.
460 * @param defaults The defaults to set.
461 */
462 public void setFrom(final Defaults defaults) {
463 licenseSetFactory.add(defaults.getLicenseSetFactory());
464 if (getStyleSheet() == null) {
465 setStyleSheet(StyleSheets.PLAIN.getStyleSheet());
466 }
467 defaults.getStandardExclusion().forEach(this::addExcludedCollection);
468 }
469
470 /**
471 * Sets the style sheet.
472 * @param styleSheet the XSLT style sheet file to style the report with.
473 */
474 public void setStyleSheet(final File styleSheet) {
475 Objects.requireNonNull(styleSheet, "styleSheet file should not be null");
476 setStyleSheet(styleSheet.toURI());
477 }
478
479 /**
480 * Sets the style sheet for custom processing. The stylesheet may be opened
481 * multiple times so the URI must be capable of being opened multiple times.
482 * @param styleSheet the URI of the XSLT style sheet to style the report with.
483 */
484 public void setStyleSheet(final URI styleSheet) {
485 Objects.requireNonNull(styleSheet, "Stylesheet file must not be null");
486 try {
487 setStyleSheet(styleSheet.toURL());
488 } catch (MalformedURLException e) {
489 throw new ConfigurationException("Unable to process stylesheet", e);
490 }
491 }
492
493 /**
494 * Sets the style sheet for custom processing. The stylesheet may be opened
495 * multiple times so the URL must be capable of being opened multiple times.
496 * @param styleSheet the URL of the XSLT style sheet to style the report with.
497 */
498 public void setStyleSheet(final URL styleSheet) {
499 Objects.requireNonNull(styleSheet, "Stylesheet file must not be null");
500 setStyleSheet(styleSheet::openStream);
501 }
502
503 /**
504 * Sets the supplier for the output stream. The supplier may be called multiple
505 * times to provide the stream. Suppliers should prepare streams that are
506 * appended to and that can be closed. If an {@code OutputStream} should not be
507 * closed consider wrapping it in a {@code NoCloseOutputStream}
508 * @param out The OutputStream supplier that provides the output stream to write
509 * the report to. A null value will use System.out.
510 * @see NoCloseOutputStream
511 */
512 public void setOut(final IOSupplier<OutputStream> out) {
513 this.out = out;
514 }
515
516 /**
517 * Sets the OutputStream supplier to use the specified file. The file may be
518 * opened and closed several times. File is deleted first and then may be
519 * repeatedly opened in append mode.
520 * @see #setOut(IOSupplier)
521 * @param file The file to create the supplier with.
522 */
523 public void setOut(final File file) {
524 Objects.requireNonNull(file, "output file should not be null");
525 if (file.exists()) {
526 try {
527 Files.delete(file.toPath());
528 } catch (IOException e) {
529 DefaultLog.getInstance().warn("Unable to delete file: " + file);
530 }
531 }
532 File parent = file.getParentFile();
533 if (!parent.mkdirs() && !parent.isDirectory()) {
534 DefaultLog.getInstance().warn("Unable to create directory: " + file.getParentFile());
535 }
536 setOut(() -> new FileOutputStream(file, true));
537 }
538
539 /**
540 * Returns the output stream supplier. If no stream has been set returns a
541 * supplier for System.out.
542 * @return The supplier of the output stream to write the report to.
543 */
544 public IOSupplier<OutputStream> getOutput() {
545 return out == null ? () -> new NoCloseOutputStream(System.out) : out;
546 }
547
548 /**
549 * Gets a PrintWriter that wraps the output stream.
550 * @return A supplier for a PrintWriter that wraps the output stream.
551 * @see #getOutput()
552 */
553 public IOSupplier<PrintWriter> getWriter() {
554 return () -> new PrintWriter(new OutputStreamWriter(getOutput().get(), StandardCharsets.UTF_8));
555 }
556
557 /**
558 * Adds a license to the list of licenses. Does not add the license to the list
559 * of approved licenses.
560 * @param license The license to add to the list of licenses.
561 */
562 public void addLicense(final ILicense license) {
563 licenseSetFactory.addLicense(license);
564 }
565
566 /**
567 * Adds a license to the list of licenses. Does not add the license to the list
568 * of approved licenses.
569 * @param builder The license builder to build and add to the list of licenses.
570 * @return The ILicense implementation that was added.
571 */
572 public ILicense addLicense(final ILicense.Builder builder) {
573 return licenseSetFactory.addLicense(builder);
574 }
575
576 /**
577 * Adds multiple licenses to the list of licenses. Does not add the licenses to
578 * the list of approved licenses.
579 * @param licenses The licenses to add.
580 */
581 public void addLicenses(final Collection<ILicense> licenses) {
582 licenseSetFactory.addLicenses(licenses);
583 }
584
585 /**
586 * Adds a license family to the list of families. Does not add the family to the
587 * list of approved licenses.
588 * @param family The license family to add to the list of license families.
589 */
590 public void addFamily(final ILicenseFamily family) {
591 licenseSetFactory.addFamily(family);
592 }
593
594 /**
595 * Adds a license family to the list of families. Does not add the family to the
596 * list of approved licenses.
597 * @param builder The licenseFamily.Builder to build and add to the list of
598 * licenses.
599 */
600 public void addFamily(final ILicenseFamily.Builder builder) {
601 licenseSetFactory.addFamily(builder);
602 }
603
604 /**
605 * Adds multiple families to the list of license families. Does not add the
606 * licenses to the list of approved licenses.
607 * @param families The license families to add.
608 */
609 public void addFamilies(final Collection<ILicenseFamily> families) {
610 families.forEach(this::addApprovedLicenseCategory);
611 }
612
613 /**
614 * Adds an ILicenseFamily to the list of approved licenses.
615 * @param approvedILicenseFamily the LicenseFamily to add.
616 */
617 public void addApprovedLicenseCategory(final ILicenseFamily approvedILicenseFamily) {
618 addApprovedLicenseCategory(approvedILicenseFamily.getFamilyCategory());
619 }
620
621 /**
622 * Adds a license family category (id) to the list of approved licenses
623 * @param familyCategory the category to add.
624 */
625 public void addApprovedLicenseCategory(final String familyCategory) {
626 licenseSetFactory.approveLicenseCategory(familyCategory);
627 }
628
629 /**
630 * Adds a collection of license family categories to the set of approved license
631 * names.
632 * @param approvedLicenseCategories set of approved license categories.
633 */
634 public void addApprovedLicenseCategories(final Collection<String> approvedLicenseCategories) {
635 approvedLicenseCategories.forEach(this::addApprovedLicenseCategory);
636 }
637
638 /**
639 * Adds a license family category to the list of approved licenses. <em>Once a
640 * license has been removed from the approved list it cannot be re-added</em>
641 * @param familyCategory the category to add.
642 */
643 public void removeApprovedLicenseCategory(final String familyCategory) {
644 licenseSetFactory.removeLicenseCategory(ILicenseFamily.makeCategory(familyCategory));
645 }
646
647 /**
648 * Removes a license family category from the list of approved licenses.
649 * <em>Once a license has been removed from the approved list it cannot be
650 * re-added</em>
651 * @param familyCategory the family category to remove.
652 */
653 public void removeApprovedLicenseCategories(final Collection<String> familyCategory) {
654 familyCategory.forEach(this::removeApprovedLicenseCategory);
655 }
656
657 /**
658 * Gets the SortedSet of approved license categories. <em>Once a license has
659 * been removed from the approved list it cannot be re-added</em>
660 * @param filter The LicenseFilter to filter the categories by.
661 * @return the Sorted set of approved license categories.
662 */
663 public SortedSet<String> getLicenseCategories(final LicenseFilter filter) {
664 return licenseSetFactory.getLicenseCategories(filter);
665 }
666
667 /**
668 * Gets the SortedSet of approved license categories. <em>Once a license has
669 * been removed from the approved list it cannot be re-added</em>
670 * @param filter The LicenseFilter to filter the licenses by.
671 * @return the Sorted set of approved license categories.
672 */
673 public SortedSet<ILicense> getLicenses(final LicenseFilter filter) {
674 return licenseSetFactory.getLicenses(filter);
675 }
676
677 /**
678 * Gets the SortedSet of approved license categories. <em>Once a license has
679 * been removed from the approved list it cannot be re-added</em>
680 * @param filter The LicenseFilter to filter the licenses by.
681 * @return the Sorted set of approved license categories.
682 */
683 public SortedSet<String> getLicenseIds(final LicenseFilter filter) {
684 return licenseSetFactory.getLicenseIds(filter);
685 }
686
687 /**
688 * Adds an ILicenseFamily to the list of approved licenses.
689 * @param approvedLicense the License to add.
690 */
691 public void addApprovedLicenseId(final ILicense approvedLicense) {
692 addApprovedLicenseId(approvedLicense.getId());
693 }
694
695 /**
696 * Adds a license family category (id) to the list of approved licenses
697 * @param licenseId the license id to add.
698 */
699 public void addApprovedLicenseId(final String licenseId) {
700 licenseSetFactory.approveLicenseId(licenseId);
701 }
702
703 /**
704 * Adds a collection of license family categories to the set of approved license
705 * names.
706 * @param approvedLicenseIds set of approved license IDs.
707 */
708 public void addApprovedLicenseIds(final Collection<String> approvedLicenseIds) {
709 approvedLicenseIds.forEach(this::addApprovedLicenseId);
710 }
711
712 /**
713 * Adds a license family category to the list of approved licenses. <em>Once a
714 * license has been removed from the approved list it cannot be re-added</em>
715 * @param licenseId the license ID to add.
716 */
717 public void removeApprovedLicenseId(final String licenseId) {
718 licenseSetFactory.removeLicenseId(licenseId);
719 }
720
721 /**
722 * Removes a license family category from the list of approved licenses.
723 * <em>Once a license has been removed from the approved list it cannot be
724 * re-added</em>
725 * @param licenseIds the license IDs to remove.
726 */
727 public void removeApprovedLicenseIds(final Collection<String> licenseIds) {
728 licenseIds.forEach(this::removeApprovedLicenseId);
729 }
730
731 /**
732 * Returns the optional license copyright being added if RAT is adding headers.
733 * This value is ignored, if no license headers are added.
734 * @return the optional copyright message.
735 * @see #isAddingLicenses()
736 */
737 public String getCopyrightMessage() {
738 return copyrightMessage;
739 }
740
741 /**
742 * Sets the optional copyright message used if RAT is adding license headers.
743 * This value is ignored, if no license headers are added.
744 * @param copyrightMessage message to set.
745 * @see #isAddingLicenses()
746 */
747 public void setCopyrightMessage(final String copyrightMessage) {
748 this.copyrightMessage = copyrightMessage;
749 }
750
751 /**
752 * Gets the flag that determines if license headers are "forced" overwriting existing files.
753 * This value is ignored if RAT is not adding licenses.
754 * @return {@code true} if RAT is forcing the adding license headers.
755 * @see #isAddingLicenses()
756 */
757 public boolean isAddingLicensesForced() {
758 return addingLicensesForced;
759 }
760
761 /**
762 * Gets the flag that determines if license headers should be added if missing.
763 * @return whether RAT should add missing license headers.
764 * @see #isAddingLicensesForced()
765 * @see #getCopyrightMessage()
766 */
767 public boolean isAddingLicenses() {
768 return addingLicenses;
769 }
770
771 /**
772 * Sets whether RAT should enable, disable, or force the adding of license
773 * headers.
774 * @param addLicenseHeaders enables/disables or forces adding of licenses
775 * headers.
776 * @see #isAddingLicenses()
777 * @see #setCopyrightMessage(String)
778 */
779 public void setAddLicenseHeaders(final AddLicenseHeaders addLicenseHeaders) {
780 addingLicenses = false;
781 addingLicensesForced = false;
782 switch (addLicenseHeaders) {
783 case FALSE:
784 // do nothing
785 break;
786 case FORCED:
787 addingLicensesForced = true;
788 addingLicenses = true;
789 break;
790 case TRUE:
791 addingLicenses = true;
792 break;
793 }
794 }
795
796 /**
797 * Gets a sorted set of ILicenseFamily objects based on {@code filter}. if
798 * filter is set:
799 * <ul>
800 * <li>{@code all} - All licenses families will be returned.</li>
801 * <li>{@code approved} - Only approved license families will be returned</li>
802 * <li>{@code none} - No license families will be returned</li>
803 * </ul>
804 * @param filter The license filter.
805 * @return The set of defined licenses.
806 */
807 public SortedSet<ILicenseFamily> getLicenseFamilies(final LicenseFilter filter) {
808 return licenseSetFactory.getLicenseFamilies(filter);
809 }
810
811 /**
812 * Gets the ClaimValidator for the configuration.
813 * @return the ClaimValidator.
814 */
815 public ClaimValidator getClaimValidator() {
816 return claimValidator;
817 }
818
819 /**
820 * Gets the enclosed LicenseSetFactory.
821 * @return the license set factory.
822 */
823 public LicenseSetFactory getLicenseSetFactory() {
824 return licenseSetFactory;
825 }
826
827 /**
828 * Validates that the configuration is valid.
829 * @param logger String consumer to log warning messages to.
830 * @throws ConfigurationException on configuration error.
831 */
832 public void validate(final Consumer<String> logger) {
833 if (!hasSource()) {
834 String msg = "At least one source must be specified";
835 logger.accept(msg);
836 throw new ConfigurationException(msg);
837 }
838 if (licenseSetFactory.getLicenses(LicenseFilter.ALL).isEmpty()) {
839 String msg = "You must specify at least one license";
840 logger.accept(msg);
841 throw new ConfigurationException(msg);
842 }
843 }
844
845 /**
846 * A wrapper around an output stream that does not close the output stream.
847 */
848 public static class NoCloseOutputStream extends OutputStream {
849 /** the output stream this stream wraps */
850 private final OutputStream delegate;
851
852 /**
853 * Constructor.
854 * @param delegate the output stream to wrap.
855 */
856 public NoCloseOutputStream(final OutputStream delegate) {
857 this.delegate = delegate;
858 }
859
860 @Override
861 public void write(final int arg0) throws IOException {
862 delegate.write(arg0);
863 }
864
865 /**
866 * Does not actually close the delegate. But does perform a flush.
867 * @throws IOException on Error.
868 */
869 @Override
870 public void close() throws IOException {
871 this.delegate.flush();
872 }
873
874 @Override
875 public boolean equals(final Object obj) {
876 return delegate.equals(obj);
877 }
878
879 @Override
880 public void flush() throws IOException {
881 delegate.flush();
882 }
883
884 @Override
885 public int hashCode() {
886 return delegate.hashCode();
887 }
888
889 @Override
890 public String toString() {
891 return delegate.toString();
892 }
893
894 @Override
895 public void write(final byte[] arg0, final int arg1, final int arg2) throws IOException {
896 delegate.write(arg0, arg1, arg2);
897 }
898
899 @Override
900 public void write(final byte[] b) throws IOException {
901 delegate.write(b);
902 }
903 }
904 }