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