This is an automated email from the ASF dual-hosted git repository.
Claudenw pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/creadur-rat.git
The following commit(s) were added to refs/heads/master by this push:
new 1f87498a RAT-568: Create IODescriptor (#695)
1f87498a is described below
commit 1f87498a381e8e732ec633732b171c1fc129de52
Author: Claude Warren <[email protected]>
AuthorDate: Wed Jul 8 11:19:35 2026 +0200
RAT-568: Create IODescriptor (#695)
* Creat IODescriptor to provide better context for input/output reporting.
Update ReportConfiguration to use IODescriptor for output and stylesheet
parameters.
Update associated classes to utilize IODescriptor.
Update tests to account for IODescriptor.
Update UI generation for IODescriptor
* updated javadoc
* added tests
* Fixed sonarqube issues
* RAT-568: Add changelog entry and fix minor issues during review
---------
Co-authored-by: P. Ottlinger <[email protected]>
---
.../java/org/apache/rat/ReportConfiguration.java | 116 +++++++++++++++-----
.../main/java/org/apache/rat/commandline/Arg.java | 3 +-
.../org/apache/rat/commandline/StyleSheets.java | 36 ++++---
.../org/apache/rat/ReportConfigurationTest.java | 120 +++++++++++++--------
.../org/apache/rat/ReporterOptionsProvider.java | 8 +-
.../src/test/java/org/apache/rat/ReporterTest.java | 22 ++--
.../test/AbstractConfigurationOptionsProvider.java | 4 +-
.../main/java/org/apache/rat/mp/RatCheckMojo.java | 2 +-
.../main/java/org/apache/rat/mp/RatReportMojo.java | 7 +-
.../main/java/org/apache/rat/anttasks/Report.java | 4 +-
.../org/apache/rat/tools/xsd/XsdGenerator.java | 2 +-
src/changes/changes.xml | 3 +
12 files changed, 212 insertions(+), 115 deletions(-)
diff --git
a/apache-rat-core/src/main/java/org/apache/rat/ReportConfiguration.java
b/apache-rat-core/src/main/java/org/apache/rat/ReportConfiguration.java
index 8fc5835d..57909582 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/ReportConfiguration.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/ReportConfiguration.java
@@ -20,6 +20,7 @@ package org.apache.rat;
import java.io.File;
import java.io.FileFilter;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -69,15 +70,20 @@ import org.apache.rat.walker.ReportableListWalker;
*/
public class ReportConfiguration {
+ /** The IODescriptor for {@code System.out}. */
+ public static final IODescriptor<OutputStream> SYSTEM_OUT =
+ // SONAR wants to require logging output, which is the wrong
reporting channel for this case.
+ new IODescriptor<>("System.out", () ->
CloseShieldOutputStream.wrap(System.out)); // NOSONAR
+
/**
* The styles of processing for various categories of documents.
*/
public enum Processing {
- /** List file as present only */
+ /** List file as present only. */
NOTIFICATION("List file as present"),
- /** List all present licenses */
+ /** List all present licenses. */
PRESENCE("List any licenses found"),
- /** List all present licenses and unknown licenses */
+ /** List all present licenses and unknown licenses. */
ABSENCE("List licenses found and any unknown licences");
/**
@@ -110,18 +116,18 @@ public class ReportConfiguration {
*/
private boolean addingLicensesForced;
/**
- * The copyright message to add if we are adding headers. Will be null if
we are not
- * adding copyright messages.
+ * The copyright message to add if we are adding headers. Will be {@code
null}
+ * if we are not adding copyright messages.
*/
private String copyrightMessage;
/**
- * The IOSupplier that provides the output stream to write the report to.
+ * The IODescriptor that provides the output stream to write the report to.
*/
- private IOSupplier<OutputStream> out;
+ private IODescriptor<OutputStream> out;
/**
- * The IOSupplier that provides the stylesheet to style the XML output.
+ * The IODescriptor that provides the stylesheet to style the XML output.
*/
- private IOSupplier<InputStream> styleSheet;
+ private IODescriptor<InputStream> styleSheet;
/**
* A list of files to read file names from.
@@ -129,7 +135,7 @@ public class ReportConfiguration {
private final List<File> sources;
/**
- * A list of reportables to process;
+ * A list of reportables to process.
*/
private final List<Reportable> reportables;
@@ -193,7 +199,7 @@ public class ReportConfiguration {
* Adds a file as a source of files to scan.
* The file must be a text file that lists files to be included.
* File within the file must be in linux format with a
- * "/" file separator.
+ * {@code "/"} file separator.
* @param file the file to process.
*/
public void addSource(final File file) {
@@ -442,16 +448,25 @@ public class ReportConfiguration {
* the report with.
*/
public IOSupplier<InputStream> getStyleSheet() {
- return styleSheet;
+ return styleSheet == null ? null : styleSheet.ioSupplier();
}
/**
- * Sets the style sheet for custom processing. The IOSupplier may be called
+ * Gets the IODescriptor with the style sheet.
+ * @return the IODescriptor that describes the XSLT style sheet to style
+ * the report with.
+ */
+ public IODescriptor<InputStream> getStyleSheetDescriptor() {
+ return styleSheet == null ? null : styleSheet;
+ }
+
+ /**
+ * Sets the style sheet for custom processing. The IODescriptor may be
called
* multiple times, so the input stream must be able to be opened and closed
* multiple times.
* @param styleSheet the XSLT style sheet to style the report with.
*/
- public void setStyleSheet(final IOSupplier<InputStream> styleSheet) {
+ public void setStyleSheet(final IODescriptor<InputStream> styleSheet) {
this.styleSheet = styleSheet;
}
@@ -499,7 +514,7 @@ public class ReportConfiguration {
*/
public void setStyleSheet(final URL styleSheet) {
Objects.requireNonNull(styleSheet, "Stylesheet file must not be null");
- setStyleSheet(styleSheet::openStream);
+ setStyleSheet(new IODescriptor<>(styleSheet.toString(),
styleSheet::openStream));
}
/**
@@ -511,7 +526,7 @@ public class ReportConfiguration {
* the report to. A null value will use System.out.
* @see CloseShieldOutputStream
*/
- public void setOut(final IOSupplier<OutputStream> out) {
+ public void setOut(final IODescriptor<OutputStream> out) {
this.out = out;
}
@@ -519,8 +534,8 @@ public class ReportConfiguration {
* Sets the OutputStream supplier to use the specified file. The file may
be
* opened and closed several times. File is deleted first and then may be
* repeatedly opened in append mode.
- * @see #setOut(IOSupplier)
- * @param file the file to create the supplier with.
+ * @see #setOut(IODescriptor)
+ * @param file The file to create the supplier with.
*/
public void setOut(final File file) {
Objects.requireNonNull(file, "output file should not be null");
@@ -535,16 +550,25 @@ public class ReportConfiguration {
if (!parent.mkdirs() && !parent.isDirectory()) {
DefaultLog.getInstance().warn("Unable to create directory: " +
file.getParentFile());
}
- setOut(() -> new FileOutputStream(file, true));
+ setOut(IODescriptor.output(file));
}
/**
* Returns the output stream supplier. If no stream has been set returns a
- * supplier for System.out.
+ * supplier for {@code System.out}.
* @return the supplier of the output stream to write the report to.
*/
public IOSupplier<OutputStream> getOutput() {
- return out == null ? () -> CloseShieldOutputStream.wrap(System.out) :
out;
+ return getOutputDescriptor().ioSupplier();
+ }
+
+ /**
+ * Returns the output IODescriptor. If no stream has been set returns a
+ * descriptor for {@code System.out}.
+ * @return the IODescriptor of the output stream to write the report to.
+ */
+ public IODescriptor<OutputStream> getOutputDescriptor() {
+ return out == null ? SYSTEM_OUT : out;
}
/**
@@ -569,7 +593,7 @@ public class ReportConfiguration {
* Adds a license to the list of licenses. Does not add the license to the
list
* of approved licenses.
* @param builder the license builder to build and add to the list of
licenses.
- * @return The ILicense implementation that was added.
+ * @return the ILicense implementation that was added.
*/
public ILicense addLicense(final ILicense.Builder builder) {
return licenseSetFactory.addLicense(builder);
@@ -796,12 +820,12 @@ public class ReportConfiguration {
}
/**
- * Gets a sorted set of ILicenseFamily objects based on {@code filter}. if
- * filter is set:
+ * Gets a sorted set of ILicenseFamily objects based on {@code filter}. If
+ * filter is set to:
* <ul>
* <li>{@code all} - All licenses families will be returned.</li>
- * <li>{@code approved} - Only approved license families will be
returned</li>
- * <li>{@code none} - No license families will be returned</li>
+ * <li>{@code approved} - Only approved license families will be
returned.</li>
+ * <li>{@code none} - No license families will be returned.</li>
* </ul>
* @param filter The license filter.
* @return The set of defined licenses.
@@ -843,4 +867,44 @@ public class ReportConfiguration {
throw new ConfigurationException(msg);
}
}
+
+ /**
+ * An IODescriptor comprises a name and an IOSupplier. The name should
identify the contents of the stream.
+ * @param name the name of the supplier.
+ * @param ioSupplier the IOSupplier that provides either an InputStream or
an OutputStream
+ * @param <T> either InputStream or OutputStream.
+ */
+ public record IODescriptor<T>(String name, IOSupplier<T> ioSupplier) {
+
+ // OUTPUT CONSTRUCTORS
+ /**
+ * Creates an output IODescriptor for the file name within the working
directory.
+ * @param name the name of the file to open.
+ * @param workingDirectory the working directory for the file.
+ * @return the Output IODescriptor.
+ */
+ static IODescriptor<OutputStream> output(final String name, final
DocumentName workingDirectory) {
+ DocumentName docName = workingDirectory.resolve(name);
+ return new IODescriptor<>(name, () -> new
FileOutputStream(docName.asFile()));
+ }
+
+ /**
+ * Creates an output IODescriptor for the file. Does not modify for
working directory.
+ * @param file the file to open.
+ * @return the Output IODescriptor.
+ */
+ static IODescriptor<OutputStream> output(final File file) {
+ return new IODescriptor<>(file.toString(), () -> new
FileOutputStream(file, true));
+ }
+
+ // INPUT CONSTRUCTORS
+ /**
+ * Creates an input IODescriptor for the file. Does not modify for
working directory.
+ * @param file the file to open.
+ * @return the Input IODescriptor.
+ */
+ static IODescriptor<InputStream> input(final File file) {
+ return new IODescriptor<>(file.toString(), () -> new
FileInputStream(file));
+ }
+ }
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
b/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
index 314e9c27..d11e9056 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
@@ -38,7 +38,6 @@ import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.output.CloseShieldOutputStream;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.rat.ConfigurationException;
import org.apache.rat.Defaults;
@@ -625,7 +624,7 @@ public enum Arg {
} catch (ParseException e) {
// we write to system out by default.
context.logParseException(e, selected, "System.out");
- context.getConfiguration().setOut(() ->
CloseShieldOutputStream.wrap(System.out)); // NOSONAR
+
context.getConfiguration().setOut(ReportConfiguration.SYSTEM_OUT);
}
}),
diff --git
a/apache-rat-core/src/main/java/org/apache/rat/commandline/StyleSheets.java
b/apache-rat-core/src/main/java/org/apache/rat/commandline/StyleSheets.java
index c73a9e4e..b56e0dde 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/commandline/StyleSheets.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/commandline/StyleSheets.java
@@ -25,8 +25,8 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
-import org.apache.commons.io.function.IOSupplier;
import org.apache.rat.ConfigurationException;
+import org.apache.rat.ReportConfiguration;
import static java.lang.String.format;
@@ -39,19 +39,20 @@ public enum StyleSheets {
*/
PLAIN("plain-rat", "The default style."),
/**
- * The missing header report style sheet
+ * The missing header report style sheet.
*/
MISSING_HEADERS("missing-headers", "Produces a report of files that are
missing headers."),
/**
- * The unapproved licenses report
+ * The unapproved licenses report.
*/
UNAPPROVED_LICENSES("unapproved-licenses", "Produces a report of the files
with unapproved licenses."),
/**
- * The plain style sheet. The current default.
+ * The pretty-printed XML style sheet.
*/
XML("xml", "Produces output in pretty-printed XML.");
+
/**
- * The name of the style sheet. Must map to bundled resource xslt file
+ * The name of the style sheet. Must map to bundled resource XSLT file
*/
private final String name;
/**
@@ -61,8 +62,8 @@ public enum StyleSheets {
/**
* Constructor.
- * @param name the name of the xslt file.
- * @param description What this xslt produces.
+ * @param name the name of the XSLT file.
+ * @param description what this XSLT produces.
*/
StyleSheets(final String name, final String description) {
this.name = name;
@@ -73,9 +74,10 @@ public enum StyleSheets {
* Gets the IOSupplier for a style sheet.
* @return an IOSupplier for the sheet.
*/
- public IOSupplier<InputStream> getStyleSheet() {
- return
Objects.requireNonNull(StyleSheets.class.getClassLoader().getResource(format("org/apache/rat/%s.xsl",
name)),
- "missing stylesheet: " + name)::openStream;
+ public ReportConfiguration.IODescriptor<InputStream> getStyleSheet() {
+ URL url =
StyleSheets.class.getClassLoader().getResource(format("org/apache/rat/%s.xsl",
name));
+ Objects.requireNonNull(url, "missing stylesheet: " + name);
+ return new ReportConfiguration.IODescriptor<>(name, url::openStream);
}
/**
@@ -83,29 +85,29 @@ public enum StyleSheets {
* @param name the short name for or the path to a style sheet.
* @return the IOSupplier for the style sheet.
*/
- public static IOSupplier<InputStream> getStyleSheet(final String name) {
+ public static ReportConfiguration.IODescriptor<InputStream>
getStyleSheet(final String name) {
URL url =
StyleSheets.class.getClassLoader().getResource(format("org/apache/rat/%s.xsl",
name));
if (url != null) {
- return url::openStream;
+ return new ReportConfiguration.IODescriptor<>(name,
url::openStream);
}
Path p = Paths.get(name);
if (p.toFile().exists()) {
- return () -> Files.newInputStream(p);
+ return new ReportConfiguration.IODescriptor<>(name, () ->
Files.newInputStream(p));
}
throw new ConfigurationException(format("Stylesheet file '%s' not
found", name));
}
/**
- * Gets the name of the xslt file.
- * @return the name of the xslt file, without the extension.
+ * Gets the name of the XSLT file.
+ * @return the name of the XSLT file, without the extension.
*/
public String arg() {
return name;
}
/**
- * Gets the description of the xslt file.
- * @return the description of the xslt file.
+ * Gets the description of the XSLT file.
+ * @return the description of the XSLT file.
*/
public String desc() {
return desc;
diff --git
a/apache-rat-core/src/test/java/org/apache/rat/ReportConfigurationTest.java
b/apache-rat-core/src/test/java/org/apache/rat/ReportConfigurationTest.java
index df346d2e..7d604043 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/ReportConfigurationTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/ReportConfigurationTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.when;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -62,7 +63,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import org.mockito.Mockito;
public class ReportConfigurationTest {
@@ -73,19 +73,19 @@ public class ReportConfigurationTest {
private File tempDir;
@BeforeEach
- public void setup() {
+ void setup() {
log = new TestingLog();
DefaultLog.setInstance(log);
underTest = new ReportConfiguration();
}
@AfterEach
- public void cleanup() {
+ void cleanup() {
DefaultLog.setInstance(null);
}
@Test
- public void testAddIncludedFilter() {
+ void testAddIncludedFilter() {
DocumentName dirName = DocumentName.builder(tempDir).build();
underTest.addExcludedFilter(DirectoryFileFilter.INSTANCE);
DocumentNameMatcher excluder = underTest.getDocumentExcluder(dirName);
@@ -98,7 +98,7 @@ public class ReportConfigurationTest {
}
@Test
- public void testAddFamilies() {
+ void testAddFamilies() {
ILicenseFamily fam1 =
ILicenseFamily.builder().setLicenseFamilyCategory("FOO").setLicenseFamilyName("found
on overview").build();
ILicenseFamily fam2 =
ILicenseFamily.builder().setLicenseFamilyCategory("BAR").setLicenseFamilyName("big
and round").build();
underTest.addFamilies(Arrays.asList(fam1, fam2));
@@ -109,13 +109,14 @@ public class ReportConfigurationTest {
}
@Test
- public void testAddApprovedLicenseId() {
+ void testAddApprovedLicenseId() {
underTest.addApprovedLicenseId("FOO");
SortedSet<String> result =
underTest.getLicenseIds(LicenseFilter.APPROVED);
assertThat(result).hasSize(1).contains("FOO");
}
+
@Test
- public void testAddAndRemoveApproveLicenseCategories() {
+ void testAddAndRemoveApproveLicenseCategories() {
List<String> expected = new ArrayList<>();
underTest.addLicense(new TestingLicense("Unapproved"));
@@ -175,7 +176,7 @@ public class ReportConfigurationTest {
}
@Test
- public void testRemoveBeforeAddApproveLicenseCategories() {
+ void testRemoveBeforeAddApproveLicenseCategories() {
underTest.addLicense( new TestingLicense("TheCat"));
assertThat(underTest.getLicenseCategories(LicenseFilter.APPROVED)).isEmpty();
assertThat(underTest.getLicenseFamilies(LicenseFilter.APPROVED)).isEmpty();
@@ -193,7 +194,7 @@ public class ReportConfigurationTest {
}
@Test
- public void testAddAndRemoveApproveLicenseIds() {
+ void testAddAndRemoveApproveLicenseIds() {
List<String> expected = new ArrayList<>();
underTest.addLicense(new TestingLicense("Unapproved"));
@@ -273,7 +274,7 @@ public class ReportConfigurationTest {
}
@Test
- public void removeFamilyAddLicense() {
+ void removeFamilyAddLicense() {
addCatz();
underTest.addApprovedLicenseCategory("catz");
underTest.removeApprovedLicenseCategory("catz");
@@ -283,7 +284,7 @@ public class ReportConfigurationTest {
}
@Test
- public void addFamilyRemoveLicense() {
+ void addFamilyRemoveLicense() {
addCatz();
underTest.addApprovedLicenseCategory("catz");
assertThat(underTest.getLicenses(LicenseFilter.APPROVED).size()).isEqualTo(7);
@@ -292,7 +293,7 @@ public class ReportConfigurationTest {
}
@Test
- public void removeFamilyRemoveLicense() {
+ void removeFamilyRemoveLicense() {
addCatz();
addDogz();
underTest.addApprovedLicenseCategory("catz");
@@ -304,7 +305,7 @@ public class ReportConfigurationTest {
}
@Test
- public void addFamilyAddLicense() {
+ void addFamilyAddLicense() {
addCatz();
addDogz();
underTest.addApprovedLicenseCategory("catz");
@@ -314,7 +315,7 @@ public class ReportConfigurationTest {
}
@Test
- public void testRemoveBeforeAddApproveLicenseIds() {
+ void testRemoveBeforeAddApproveLicenseIds() {
underTest.addLicense( new TestingLicense("TheCat"));
assertThat(underTest.getLicenseIds(LicenseFilter.APPROVED)).isEmpty();
assertThat(underTest.getLicenses(LicenseFilter.APPROVED)).isEmpty();
@@ -335,7 +336,7 @@ public class ReportConfigurationTest {
}
@Test
- public void testAddLicense() {
+ void testAddLicense() {
List<ILicense> expected = new ArrayList<>();
assertThat(underTest.getLicenses(LicenseFilter.ALL)).isEmpty();
@@ -353,17 +354,18 @@ public class ReportConfigurationTest {
}
@Test
- public void copyrightMessageTest() {
+ void copyrightMessageTest() {
assertThat(underTest.getCopyrightMessage()).isNull();
underTest.setCopyrightMessage("This is the message");
assertThat(underTest.getCopyrightMessage()).isEqualTo("This is the
message");
}
- DocumentName mkDocumentName(File f) {
+ private DocumentName mkDocumentName(File f) {
return DocumentName.builder(f).setBaseName(tempDir).build();
}
+
@Test
- public void exclusionTest() {
+ void inclusionExclusionTest() {
DocumentName baseDir = DocumentName.builder(tempDir).build();
DocumentName foo = mkDocumentName(new File(tempDir,"foo"));
assertThat(underTest.getDocumentExcluder(baseDir).matches(foo)).isTrue();
@@ -378,19 +380,24 @@ public class ReportConfigurationTest {
underTest.addIncludedCollection(StandardCollection.HIDDEN_DIR);
assertThat(underTest.getDocumentExcluder(baseDir).matches(hiddenDir)).isTrue();
-
+ // explicitly adding again does not change test
underTest.addExcludedCollection(StandardCollection.HIDDEN_DIR);
assertThat(underTest.getDocumentExcluder(baseDir).matches(hiddenDir)).isTrue();
- underTest.addExcludedFilter(DirectoryFileFilter.DIRECTORY);
+ DocumentName percentName = mkDocumentName(new File(tempDir,
"%hello%"));
+
assertThat(underTest.getDocumentExcluder(baseDir).matches(percentName)).isFalse();
+ FileFilter percentFilter = file -> file.getName().endsWith("%hello%");
+ underTest.addIncludedFilter(percentFilter);
+
assertThat(underTest.getDocumentExcluder(baseDir).matches(percentName)).isTrue();
+ underTest.addExcludedFilter(DirectoryFileFilter.DIRECTORY);
File file = new File(tempDir, "newDir");
assertThat(file.mkdirs()).as(() -> "Could not create directory " +
file).isTrue();
assertThat(underTest.getDocumentExcluder(baseDir).matches(mkDocumentName(file))).isFalse();
}
@Test
- public void archiveProcessingTest() {
+ void archiveProcessingTest() {
assertThat(underTest.getArchiveProcessing()).isEqualTo(ReportConfiguration.Processing.NOTIFICATION);
underTest.setFrom(Defaults.builder().build());
@@ -407,7 +414,7 @@ public class ReportConfigurationTest {
}
@Test
- public void licenseFamiliesTest() {
+ void licenseFamiliesTest() {
assertThat(underTest.getLicenseFamilies(LicenseFilter.ALL)).isEmpty();
assertThat(underTest.getLicenseFamilies(LicenseFilter.APPROVED)).isEmpty();
assertThat(underTest.getLicenseFamilies(LicenseFilter.NONE)).isEmpty();
@@ -429,7 +436,7 @@ public class ReportConfigurationTest {
}
@Test
- public void licensesTest() {
+ void licensesTest() {
assertThat(underTest.getLicenses(LicenseFilter.ALL)).isEmpty();
assertThat(underTest.getLicenses(LicenseFilter.APPROVED)).isEmpty();
assertThat(underTest.getLicenses(LicenseFilter.NONE)).isEmpty();
@@ -451,12 +458,12 @@ public class ReportConfigurationTest {
}
@Test
- public void outputTest() throws IOException {
+ void outputTest() throws IOException {
assertThat(underTest.getOutput().get()).isExactlyInstanceOf(CloseShieldOutputStream.class);
assertThat(underTest.getWriter()).isNotNull();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
- underTest.setOut(() -> stream);
+ underTest.setOut(new ReportConfiguration.IODescriptor("outputTest", ()
-> stream));
assertThat(underTest.getOutput().get()).isEqualTo(stream);
PrintWriter writer = underTest.getWriter().get();
assertThat(writer).isNotNull();
@@ -466,7 +473,7 @@ public class ReportConfigurationTest {
}
@Test
- public void reportableTest() {
+ void reportableTest() {
assertThat(underTest.hasSource()).isFalse();
Reportable reportable = mock(Reportable.class);
underTest.addSource(reportable);
@@ -476,13 +483,15 @@ public class ReportConfigurationTest {
}
@Test
- public void stylesheetTest() throws IOException, URISyntaxException {
+ void stylesheetTest() throws IOException, URISyntaxException {
URL url = this.getClass().getResource("ReportConfigurationTestFile");
assertThat(url).isNotNull();
+ assertThat(underTest.getStyleSheetDescriptor()).isNull();
assertThat(underTest.getStyleSheet()).isNull();
InputStream stream = mock(InputStream.class);
- underTest.setStyleSheet(() -> stream);
+ underTest.setStyleSheet(new
ReportConfiguration.IODescriptor("stylesheetTest", () -> stream));
+
assertThat(underTest.getStyleSheetDescriptor().ioSupplier().get()).isEqualTo(stream);
assertThat(underTest.getStyleSheet().get()).isEqualTo(stream);
File file = mock(File.class);
@@ -493,10 +502,13 @@ public class ReportConfigurationTest {
BufferedReader d = new BufferedReader(new
InputStreamReader(underTest.getStyleSheet().get()));
assertThat(d.readLine()).isEqualTo("/*");
assertThat(d.readLine()).isEqualTo(" * Licensed to the Apache Software
Foundation (ASF) under one *");
+ d = new BufferedReader(new
InputStreamReader(underTest.getStyleSheetDescriptor().ioSupplier().get()));
+ assertThat(d.readLine()).isEqualTo("/*");
+ assertThat(d.readLine()).isEqualTo(" * Licensed to the Apache Software
Foundation (ASF) under one *");
}
@Test
- public void testFlags() {
+ void testFlags() {
assertThat(underTest.isAddingLicenses()).isFalse();
assertThat(underTest.isAddingLicensesForced()).isFalse();
@@ -514,14 +526,13 @@ public class ReportConfigurationTest {
}
@Test
- public void testValidate() {
+ void testValidate() {
final StringBuilder sb = new StringBuilder();
String msg = "At least one source must be specified";
assertThatThrownBy(() ->
underTest.validate(sb::append)).isExactlyInstanceOf(ConfigurationException.class)
.hasMessageContaining(msg);
assertThat(sb.toString()).isEqualTo(msg);
-
sb.setLength(0);
msg = "You must specify at least one license";
underTest.addSource(mock(Reportable.class));
@@ -537,10 +548,10 @@ public class ReportConfigurationTest {
}
@Test
- public void testSetOut() throws IOException {
+ void testSetOut() throws IOException {
ReportConfiguration config = new ReportConfiguration();
try (OutputStreamInterceptor osi = new OutputStreamInterceptor()) {
- config.setOut(() -> osi);
+ config.setOut(new ReportConfiguration.IODescriptor("testSetOut",()
-> osi));
assertThat(osi.closeCount).isEqualTo(0);
try (OutputStream os = config.getOutput().get()) {
assertThat(os).isNotNull();
@@ -556,7 +567,7 @@ public class ReportConfigurationTest {
}
@Test
- public void logFamilyCollisionTest() {
+ void logFamilyCollisionTest() {
// setup
underTest.addFamily(ILicenseFamily.builder().setLicenseFamilyCategory("CAT").setLicenseFamilyName("name"));
assertThat(log.getCaptured()).doesNotContain("CAT");
@@ -577,7 +588,7 @@ public class ReportConfigurationTest {
}
@Test
- public void familyDuplicateOptionsTest() {
+ void familyDuplicateOptionsTest() {
underTest.addFamily(ILicenseFamily.builder().setLicenseFamilyCategory("CAT").setLicenseFamilyName("name"));
assertThat(log.getCaptured()).doesNotContain("CAT");
@@ -605,10 +616,10 @@ public class ReportConfigurationTest {
}
@Test
- public void logLicenseCollisionTest() {
+ void logLicenseCollisionTest() {
// setup
ILicenseFamily family =
ILicenseFamily.builder().setLicenseFamilyCategory("CAT").setLicenseFamilyName("family
name").build();
- IHeaderMatcher matcher = Mockito.mock(IHeaderMatcher.class);
+ IHeaderMatcher matcher = mock(IHeaderMatcher.class);
when(matcher.getId()).thenReturn("Macher ID");
underTest.addFamily(family);
underTest.addLicense(ILicense.builder().setId("ID").setName("license
name").setFamily(family.getFamilyCategory())
@@ -633,10 +644,10 @@ public class ReportConfigurationTest {
}
@Test
- public void licenseDuplicateOptionsTest() {
+ void licenseDuplicateOptionsTest() {
// setup
ILicenseFamily family =
ILicenseFamily.builder().setLicenseFamilyCategory("CAT").setLicenseFamilyName("family
name").build();
- IHeaderMatcher matcher = Mockito.mock(IHeaderMatcher.class);
+ IHeaderMatcher matcher = mock(IHeaderMatcher.class);
when(matcher.getId()).thenReturn("Macher ID");
underTest.addFamily(family);
Function<String,ILicense> makeLicense = s ->
ILicense.builder().setId("ID").setName(s).setFamily(family.getFamilyCategory())
@@ -662,9 +673,34 @@ public class ReportConfigurationTest {
.isExactlyInstanceOf(IllegalArgumentException.class);
}
+ @Test
+ void reportExclusionErrorTest() {
+ Appendable appendable = new Appendable(){
+ @Override
+ public Appendable append(CharSequence csq) throws IOException {
+ throw new IOException("BANG!");
+ }
+
+ @Override
+ public Appendable append(CharSequence csq, int start, int end)
throws IOException {
+ throw new IOException("BANG!");
+ }
+
+ @Override
+ public Appendable append(char c) throws IOException {
+ throw new IOException("BANG!");
+ }
+ };
+
+ underTest.reportExclusions(appendable);
+ assertThat(log.getCaptured())
+ .contains("WARN: Unable to report exclusions")
+ .contains("java.io.IOException: BANG!");
+ }
+
/**
* Validates that the configuration contains the default approved licenses.
- * @param config The configuration to test.
+ * @param config the configuration to test.
*/
public static void validateDefaultApprovedLicenses(ReportConfiguration
config) {
validateDefaultApprovedLicenses(config, 0);
@@ -672,7 +708,7 @@ public class ReportConfigurationTest {
/**
* Validates that the configuration contains the default approved licenses.
- * @param config The configuration to test.
+ * @param config the configuration to test.
*/
public static void validateDefaultApprovedLicenses(ReportConfiguration
config, int additionalIdCount) {
assertThat(config.getLicenseCategories(LicenseFilter.APPROVED)).hasSize(XMLConfigurationReaderTest.APPROVED_IDS.length
+ additionalIdCount);
@@ -711,7 +747,7 @@ public class ReportConfigurationTest {
/**
* Validates that the configuration matches the default.
- * @param config The configuration to test.
+ * @param config the configuration to test.
*/
public static void validateDefault(ReportConfiguration config) {
assertThat(config.isAddingLicenses()).isFalse();
diff --git
a/apache-rat-core/src/test/java/org/apache/rat/ReporterOptionsProvider.java
b/apache-rat-core/src/test/java/org/apache/rat/ReporterOptionsProvider.java
index 0ef6f019..bd9e4fd6 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/ReporterOptionsProvider.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/ReporterOptionsProvider.java
@@ -75,7 +75,7 @@ class ReporterOptionsProvider extends AbstractOptionsProvider
implements Argumen
static File sourceDir;
/**
- * A flag to determine if help was called
+ * A flag to determine if help was called.
*/
final AtomicBoolean helpCalled = new AtomicBoolean(false);
@@ -93,7 +93,7 @@ class ReporterOptionsProvider extends AbstractOptionsProvider
implements Argumen
* Forces the {@code helpCalled} flag to be reset.
*
* @param args the arguments.
- * @return A ReportConfiguration
+ * @return a ReportConfiguration
* @throws IOException on critical error.
*/
@Override
@@ -691,7 +691,6 @@ class ReporterOptionsProvider extends
AbstractOptionsProvider implements Argumen
new String[]{"BSD-3"});
}
-
private void configTest(final Option option) {
assertDoesNotThrow(() -> {
configureSourceDir(option);
@@ -725,7 +724,6 @@ class ReporterOptionsProvider extends
AbstractOptionsProvider implements Argumen
assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
-
});
}
@@ -939,7 +937,7 @@ class ReporterOptionsProvider extends
AbstractOptionsProvider implements Argumen
String actualText = baos.toString(StandardCharsets.UTF_8);
TextUtils.assertContainsExactly(1, "<resource
encoding=\"ISO-8859-1\" mediaType=\"text/plain\" name=\"/stylesheet\"
type=\"STANDARD\">", actualText);
- try (InputStream expected = StyleSheets.getStyleSheet("xml").get();
+ try (InputStream expected =
StyleSheets.getStyleSheet("xml").ioSupplier().get();
InputStream actual = config.getStyleSheet().get()) {
assertThat(IOUtils.contentEquals(expected, actual)).as("'xml'
does not match").isTrue();
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/ReporterTest.java
b/apache-rat-core/src/test/java/org/apache/rat/ReporterTest.java
index 3d9c84e7..d9f11b7a 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/ReporterTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/ReporterTest.java
@@ -81,7 +81,7 @@ public class ReporterTest {
}
@Test
- public void testExecute() throws RatException, ParseException {
+ void testExecute() throws RatException, ParseException {
File output = new File(tempDirectory, "testExecute");
CommandLine cl = new
DefaultParser().parse(OptionCollection.buildOptions(), new
String[]{"--output-style", "xml", "--output-file", output.getPath(), basedir});
@@ -136,7 +136,7 @@ public class ReporterTest {
}
@Test
- public void testOutputOption() throws Exception {
+ void testOutputOption() throws Exception {
File output = new File(tempDirectory, "test");
CommandLine commandLine = new
DefaultParser().parse(OptionCollection.buildOptions(), new String[]{"-o",
output.getCanonicalPath(), basedir});
ArgumentContext ctxt = new ArgumentContext(new File("."), commandLine);
@@ -151,7 +151,7 @@ public class ReporterTest {
}
@Test
- public void testDefaultOutput() throws Exception {
+ void testDefaultOutput() throws Exception {
File output = new File(tempDirectory, "testDefaultOutput");
PrintStream origin = System.out;
@@ -179,7 +179,7 @@ public class ReporterTest {
}
@Test
- public void testXMLOutput() throws Exception {
+ void testXMLOutput() throws Exception {
Map<String, Map<String, String>> expected = new HashMap<>();
expected.put("/.hiddenDirectory", mapOf("isDirectory", "true",
"mediaType", "application/octet-stream",
"type", "IGNORED"));
@@ -404,12 +404,12 @@ public class ReporterTest {
}
@Test
- public void xmlReportTest() throws Exception {
+ void xmlReportTest() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ReportConfiguration configuration = initializeConfiguration();
configuration.setStyleSheet(StyleSheets.XML.getStyleSheet());
- configuration.setOut(() -> out);
+ configuration.setOut(new
ReportConfiguration.IODescriptor("xmlReportTest", () -> out));
new Reporter(configuration).output();
Document doc = XmlUtils.toDom(new
ByteArrayInputStream(out.toByteArray()));
@@ -448,7 +448,7 @@ public class ReporterTest {
}
@Test
- public void plainReportTest() throws Exception {
+ void plainReportTest() throws Exception {
final String NL = System.lineSeparator();
final String SEPARATOR =
"*****************************************************";
final String HEADER = SEPARATOR + NL + //
@@ -457,7 +457,7 @@ public class ReporterTest {
"Generated at: ";
ByteArrayOutputStream out = new ByteArrayOutputStream();
ReportConfiguration configuration = initializeConfiguration();
- configuration.setOut(() -> out);
+ configuration.setOut(new
ReportConfiguration.IODescriptor("plainReportTest", () -> out));
new Reporter(configuration).output();
out.flush();
@@ -470,10 +470,10 @@ public class ReporterTest {
}
@Test
- public void unapprovedLicensesReportTest() throws Exception {
+ void unapprovedLicensesReportTest() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ReportConfiguration configuration = initializeConfiguration();
- configuration.setOut(() -> out);
+ configuration.setOut(new
ReportConfiguration.IODescriptor("unapprovedLicensesReportTest", () -> out));
configuration.setStyleSheet(this.getClass().getResource("/org/apache/rat/unapproved-licenses.xsl"));
new Reporter(configuration).output();
@@ -489,7 +489,7 @@ public class ReporterTest {
void listLicensesReportTest() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ReportConfiguration configuration = initializeConfiguration();
- configuration.setOut(() -> out);
+ configuration.setOut(new
ReportConfiguration.IODescriptor("listLicensesReportTest", () -> out));
configuration.setStyleSheet(StyleSheets.UNAPPROVED_LICENSES.getStyleSheet());
Reporter.listLicenses(configuration,
LicenseSetFactory.LicenseFilter.NONE);
diff --git
a/apache-rat-core/src/test/java/org/apache/rat/test/AbstractConfigurationOptionsProvider.java
b/apache-rat-core/src/test/java/org/apache/rat/test/AbstractConfigurationOptionsProvider.java
index 5d34d80a..84e30dc5 100644
---
a/apache-rat-core/src/test/java/org/apache/rat/test/AbstractConfigurationOptionsProvider.java
+++
b/apache-rat-core/src/test/java/org/apache/rat/test/AbstractConfigurationOptionsProvider.java
@@ -818,7 +818,7 @@ public abstract class AbstractConfigurationOptionsProvider
extends AbstractOptio
for (String sheet : new String[]{"plain-rat", "missing-headers",
"unapproved-licenses", file.getAbsolutePath()}) {
args[0] = sheet;
ReportConfiguration config =
generateConfig(ImmutablePair.of(option, args));
- try (InputStream expected =
StyleSheets.getStyleSheet(sheet).get();
+ try (InputStream expected =
StyleSheets.getStyleSheet(sheet).ioSupplier().get();
InputStream actual = config.getStyleSheet().get()) {
assertThat(IOUtils.contentEquals(expected, actual)).as(()
-> String.format("'%s' does not match", sheet)).isTrue();
}
@@ -845,7 +845,7 @@ public abstract class AbstractConfigurationOptionsProvider
extends AbstractOptio
protected void xmlTest() {
assertDoesNotThrow(() -> {
ReportConfiguration config =
generateConfig(ImmutablePair.of(Arg.OUTPUT_STYLE.find("xml"), null));
- try (InputStream expected = StyleSheets.getStyleSheet("xml").get();
+ try (InputStream expected =
StyleSheets.getStyleSheet("xml").ioSupplier().get();
InputStream actual = config.getStyleSheet().get()) {
assertThat(IOUtils.contentEquals(expected, actual)).as("'xml'
does not match").isTrue();
}
diff --git
a/apache-rat-plugin/src/main/java/org/apache/rat/mp/RatCheckMojo.java
b/apache-rat-plugin/src/main/java/org/apache/rat/mp/RatCheckMojo.java
index 7bd6b1da..5a55a061 100644
--- a/apache-rat-plugin/src/main/java/org/apache/rat/mp/RatCheckMojo.java
+++ b/apache-rat-plugin/src/main/java/org/apache/rat/mp/RatCheckMojo.java
@@ -234,7 +234,7 @@ public class RatCheckMojo extends AbstractRatMojo {
!config.getClaimValidator().isValid(ClaimStatistic.Counter.UNAPPROVED,
statistics.getCounter(ClaimStatistic.Counter.UNAPPROVED))) {
try {
ByteArrayOutputStream baos = new
ByteArrayOutputStream();
-
reporter.output(StyleSheets.UNAPPROVED_LICENSES.getStyleSheet(), () -> baos);
+
reporter.output(StyleSheets.UNAPPROVED_LICENSES.getStyleSheet().ioSupplier(),
() -> baos);
getLog().warn(baos.toString(StandardCharsets.UTF_8));
} catch (RuntimeException rte) {
throw rte;
diff --git
a/apache-rat-plugin/src/main/java/org/apache/rat/mp/RatReportMojo.java
b/apache-rat-plugin/src/main/java/org/apache/rat/mp/RatReportMojo.java
index 330d3c5e..99ac97f5 100644
--- a/apache-rat-plugin/src/main/java/org/apache/rat/mp/RatReportMojo.java
+++ b/apache-rat-plugin/src/main/java/org/apache/rat/mp/RatReportMojo.java
@@ -90,7 +90,6 @@ public class RatReportMojo extends AbstractRatMojo implements
MavenMultiPageRepo
@Parameter(property = "outputEncoding", defaultValue =
"${project.reporting.outputEncoding}", readonly = true)
private String outputEncoding;
-
/**
* The local repository.
*/
@@ -153,9 +152,7 @@ public class RatReportMojo extends AbstractRatMojo
implements MavenMultiPageRepo
}
File outputDirectory = new File(getOutputDirectory());
-
String filename = getOutputName() + ".html";
-
Locale locale = Locale.getDefault();
try {
@@ -182,7 +179,6 @@ public class RatReportMojo extends AbstractRatMojo
implements MavenMultiPageRepo
// render report
getSiteRenderer().mergeDocumentIntoSite(writer, sink,
siteContext);
}
-
}
// copy generated resources also
@@ -264,7 +260,6 @@ public class RatReportMojo extends AbstractRatMojo
implements MavenMultiPageRepo
this.sinkFactory = sinkFactory;
if (!(sink instanceof SiteRendererSink)) {
-
generateReportManually(locale);
} else {
executeReport(locale);
@@ -446,7 +441,7 @@ public class RatReportMojo extends AbstractRatMojo
implements MavenMultiPageRepo
config.reportExclusions(logWriter);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- config.setOut(() -> baos);
+ config.setOut(new ReportConfiguration.IODescriptor("RAT
output", () -> baos));
Reporter reporter = new Reporter(config);
reporter.output();
if (verbose) {
diff --git a/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Report.java
b/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Report.java
index a069084f..cd91a8ec 100644
--- a/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Report.java
+++ b/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Report.java
@@ -416,7 +416,7 @@ public class Report extends BaseAntTask {
o -> DefaultLog.getInstance().warn("Help option not
supported"),
true);
if (getValues(Arg.OUTPUT_FILE).isEmpty()) {
- configuration.setOut(() -> new LogOutputStream(this,
Project.MSG_INFO));
+ configuration.setOut(new
ReportConfiguration.IODescriptor<>("RAT output", () -> new
LogOutputStream(this, Project.MSG_INFO)));
}
DocumentName name =
DocumentName.builder(getProject().getBaseDir()).build();
configuration.addSource(new ResourceCollectionContainer(name,
configuration, nestedResources));
@@ -444,7 +444,7 @@ public class Report extends BaseAntTask {
public void execute() {
try {
Reporter r = new Reporter(validate(getConfiguration()));
- r.output(StyleSheets.PLAIN.getStyleSheet(), () ->
CloseShieldOutputStream.wrap(System.out));
+ r.output(StyleSheets.PLAIN.getStyleSheet().ioSupplier(), () ->
CloseShieldOutputStream.wrap(System.out));
r.output();
} catch (BuildException e) {
throw e;
diff --git
a/apache-rat-tools/src/main/java/org/apache/rat/tools/xsd/XsdGenerator.java
b/apache-rat-tools/src/main/java/org/apache/rat/tools/xsd/XsdGenerator.java
index b3860c12..eafcc4e4 100644
--- a/apache-rat-tools/src/main/java/org/apache/rat/tools/xsd/XsdGenerator.java
+++ b/apache-rat-tools/src/main/java/org/apache/rat/tools/xsd/XsdGenerator.java
@@ -70,7 +70,7 @@ public class XsdGenerator {
XsdGenerator generator = new XsdGenerator();
try (InputStream in = generator.getInputStream();
- InputStream styleIn = StyleSheets.XML.getStyleSheet().get()) {
+ InputStream styleIn =
StyleSheets.XML.getStyleSheet().ioSupplier().get()) {
StandardXmlFactory.createTransformer(styleIn).transform(new
StreamSource(in),
new StreamResult(new OutputStreamWriter(System.out,
StandardCharsets.UTF_8)));
}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 120786a1..6d37b83a 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -68,6 +68,9 @@ in order to be properly linked in site reports.
</release>
-->
<release version="1.0.0-SNAPSHOT" date="xxxx-yy-zz" description="Current
SNAPSHOT - release to be done">
+ <action issue="RAT-568" type="add" dev="claudenw">
+ Internal change to prepare a better UI testing: create and utilize an
IODescriptor that will have a name associated with the current IOSupplier that
is in use.
+ </action>
<action issue="RAT-564" type="add" dev="claudenw">
Internal change to let LicenseSetFactory return unmodifiable license
sets.
</action>