Merge pull request #246 from Claudenw/create_archive_processor
RAT-372: Create archive processor
diff --git a/apache-rat-core/pom.xml b/apache-rat-core/pom.xml
index a4ad439..6c48473 100644
--- a/apache-rat-core/pom.xml
+++ b/apache-rat-core/pom.xml
@@ -97,6 +97,10 @@
</exclusions>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
diff --git a/apache-rat-core/src/main/java/org/apache/rat/Defaults.java b/apache-rat-core/src/main/java/org/apache/rat/Defaults.java
index be0456b..05c4ed8 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/Defaults.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/Defaults.java
@@ -44,7 +44,6 @@
/**
* A class that provides the standard system defaults for the ReportConfiguration.
- *
* Properties in this class may be overridden or added to by configuration options in the various UIs.
* See the specific UI for details.
*/
@@ -63,14 +62,21 @@
*/
public static final String UNAPPROVED_LICENSES_STYLESHEET = "org/apache/rat/unapproved-licenses.xsl";
+ public static final FilenameFilter FILES_TO_IGNORE = FalseFileFilter.FALSE;
+
+ public static final IOFileFilter DIRECTORIES_TO_IGNORE = NameBasedHiddenFileFilter.HIDDEN;
+
+ public static final ReportConfiguration.Processing ARCHIVE_PROCESSING = ReportConfiguration.Processing.NOTIFICATION;
+
+ public static final LicenseFilter LIST_FAMILIES = LicenseFilter.NONE;
+
+ public static final LicenseFilter LIST_LICENSES = LicenseFilter.NONE;
+
private final LicenseSetFactory setFactory;
- private static final FilenameFilter FILES_TO_IGNORE = FalseFileFilter.FALSE;
-
- private static final IOFileFilter DIRECTORIES_TO_IGNORE = NameBasedHiddenFileFilter.HIDDEN;
/**
- * Initialize the system configuration reader..
+ * Initialize the system configuration reader.
*/
public static void init() {
Format fmt = Format.fromURL(DEFAULT_CONFIG_URL);
@@ -166,14 +172,6 @@
public SortedSet<String> getLicenseIds(final LicenseFilter filter) {
return setFactory.getLicenseFamilyIds(filter);
}
-
- public static FilenameFilter getFilesToIgnore() {
- return FILES_TO_IGNORE;
- }
-
- public static IOFileFilter getDirectoriesToIgnore() {
- return DIRECTORIES_TO_IGNORE;
- }
/**
* The Defaults builder.
diff --git a/apache-rat-core/src/main/java/org/apache/rat/Report.java b/apache-rat-core/src/main/java/org/apache/rat/Report.java
index 6a8ea88..fc0e187 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/Report.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/Report.java
@@ -22,7 +22,7 @@
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
-import java.io.PrintStream;
+import java.io.PrintWriter;
import java.io.Serializable;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@@ -31,11 +31,15 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
import java.util.function.Consumer;
+import java.util.function.Supplier;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Converter;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
@@ -43,6 +47,7 @@
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.FalseFileFilter;
import org.apache.commons.io.filefilter.NameFileFilter;
import org.apache.commons.io.filefilter.NotFileFilter;
import org.apache.commons.io.filefilter.OrFileFilter;
@@ -50,7 +55,10 @@
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.commons.io.function.IOSupplier;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.WordUtils;
+import org.apache.rat.api.Document;
import org.apache.rat.config.AddLicenseHeaders;
+import org.apache.rat.document.impl.FileDocument;
import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
import org.apache.rat.report.IReportable;
import org.apache.rat.utils.DefaultLog;
@@ -59,74 +67,198 @@
import org.apache.rat.walker.ArchiveWalker;
import org.apache.rat.walker.DirectoryWalker;
+import static java.lang.String.format;
+
/**
* The CLI based configuration object for report generation.
*/
public class Report {
+
+ private static final String[] NOTES = {
+ "Rat highlights possible issues.",
+ "Rat reports require interpretation.",
+ "Rat often requires some tuning before it runs well against a project.",
+ "Rat relies on heuristics: it may miss issues"
+ };
+
+ private enum StyleSheets { PLAIN("plain-rat", "The default style"),
+ MISSING_HEADERS("missing-headers", "Produces a report of files that are missing headers"),
+ UNAPPROVED_LICENSES("unapproved-licenses", "Produces a report of the files with unapproved licenses");
+ private final String arg;
+ private final String desc;
+ StyleSheets(String arg, String description) {
+ this.arg = arg;
+ this.desc = description;
+ }
+
+ public String arg() {
+ return arg;
+ }
+
+ public String desc() {
+ return desc;
+ }
+ }
+
+ private static final Map<String, Supplier<String>> ARGUMENT_TYPES;
+
+ static {
+ ARGUMENT_TYPES = new TreeMap<>();
+ ARGUMENT_TYPES.put("FileOrURI", () -> "A file name or URI");
+ ARGUMENT_TYPES.put("DirOrArchive", () -> "A directory or archive file to scan");
+ ARGUMENT_TYPES.put("Expression", () -> "A wildcard file matching pattern. example: *-test-*.txt");
+ ARGUMENT_TYPES.put("LicenseFilter", () -> format("A defined filter for the licenses to include. Valid values: %s.",
+ asString(LicenseFilter.values())));
+ ARGUMENT_TYPES.put("LogLevel", () -> format("The log level to use. Valid values %s.", asString(Log.Level.values())));
+ ARGUMENT_TYPES.put("ProcessingType", () -> format("Specifies how to process file types. Valid values are: %s",
+ Arrays.stream(ReportConfiguration.Processing.values())
+ .map(v -> format("\t%s: %s", v.name(), v.desc()))
+ .collect(Collectors.joining(""))));
+ ARGUMENT_TYPES.put("StyleSheet", () -> format("Either an external xsl file or maybe one of the internal named sheets. Internal sheets are: %s.",
+ Arrays.stream(StyleSheets.values())
+ .map(v -> format("\t%s: %s", v.arg(), v.desc()))
+ .collect(Collectors.joining(""))));
+ }
+
+ // RAT-85/RAT-203: Deprecated! added only for convenience and for backwards
+ // compatibility
/**
* Adds license headers to files missing headers.
*/
- private static final String ADD = "A";
- private static final String ADD_OLD = "a";
+ private static final OptionGroup ADD = new OptionGroup()
+ .addOption(new Option("a", false,
+ "(deprecated) Add the default license header to any file with an unknown license. Use '-A' or ---addLicense instead."))
+ .addOption(new Option("A", "addLicense", false,
+ "Add the default license header to any file with an unknown license that is not in the exclusion list. "
+ + "By default new files will be created with the license header, "
+ + "to force the modification of existing files use the --force option.")
+ );
+
+ /**
+ * Defines the output for the file.
+ * @since 0.16.0
+ */
+ static final Option OUT = Option.builder().option("o").longOpt("out").hasArg()
+ .desc("Define the output file where to write a report to (default is System.out).")
+ .converter(Converter.FILE).build();
+
+ static final Option DIR = Option.builder().option("d").longOpt("dir").hasArg()
+ .desc("(deprecated, use '--') Used to indicate source when using --exclude.").argName("DirOrArchive").build();
+
/**
* Forces changes to be written to new files.
*/
- private static final String FORCE = "f";
+ static final Option FORCE = new Option("f", "force", false,
+ "Forces any changes in files to be written directly to the source files (i.e. new files are not created).");
/**
* Defines the copyright header to add to the file.
*/
- private static final String COPYRIGHT = "c";
+ static final Option COPYRIGHT = Option.builder().option("c").longOpt("copyright").hasArg()
+ .desc("The copyright message to use in the license headers, usually in the form of \"Copyright 2008 Foo\"")
+ .build();
/**
* Name of File to exclude from report consideration.
*/
- private static final String EXCLUDE_CLI = "e";
+ static final Option EXCLUDE_CLI = Option.builder("e").longOpt("exclude").hasArgs().argName("Expression")
+ .desc("Excludes files matching wildcard <expression>. May be followed by multiple arguments. "
+ + "Note that '--' or a following option is required when using this parameter.")
+ .build();
/**
* Name of file that contains a list of files to exclude from report
* consideration.
*/
- private static final String EXCLUDE_FILE_CLI = "E";
+ static final Option EXCLUDE_FILE_CLI = Option.builder("E").longOpt("exclude-file")
+ .argName("FileOrURI")
+ .hasArg().desc("Excludes files matching regular expression in the input file.")
+ .build();
+
/**
* The stylesheet to use to style the XML output.
*/
- private static final String STYLESHEET_CLI = "s";
+ static final Option STYLESHEET_CLI = Option.builder("s").longOpt("stylesheet").hasArg().argName("StyleSheet")
+ .desc("XSLT stylesheet to use when creating the report. Not compatible with -x. " +
+ "Either an external xsl file may be specified or one of the internal named sheets: plain-rat (default), missing-headers, or unapproved-licenses")
+ .build();
/**
* Produce help
*/
- private static final String HELP = "h";
+ static final Option HELP = new Option("h", "help", false, "Print help for the RAT command line interface and exit.");
/**
* Flag to identify a file with license definitions.
+ * @since 0.16.0
*/
- private static final String LICENSES = "licenses";
+ static final Option LICENSES = Option.builder().longOpt("licenses").hasArgs().argName("FileOrURI")
+ .desc("File names or URLs for license definitions")
+ .build();
/**
* Do not use the default files.
+ * @since 0.16.0
*/
- private static final String NO_DEFAULTS = "no-default-licenses";
+ static final Option NO_DEFAULTS = new Option(null, "no-default-licenses", false, "Ignore default configuration. By default all approved default licenses are used");
+
/**
* Scan hidden directories.
*/
- private static final String SCAN_HIDDEN_DIRECTORIES = "scan-hidden-directories";
+ static final Option SCAN_HIDDEN_DIRECTORIES = new Option(null, "scan-hidden-directories", false, "Scan hidden directories");
+
/**
* List the licenses that were used for the run.
+ * @since 0.16.0
*/
- private static final String LIST_LICENSES = "list-licenses";
+ static final Option LIST_LICENSES = Option.builder().longOpt("list-licenses").hasArg().argName("LicenseFilter")
+ .desc("List the defined licenses (default is NONE). Valid options are: " + asString(LicenseFilter.values()))
+ .converter(s -> LicenseFilter.valueOf(s.toUpperCase()))
+ .build();
/**
* List the all families for the run.
+ * @since 0.16.0
*/
- private static final String LIST_FAMILIES = "list-families";
+ static final Option LIST_FAMILIES = Option.builder().longOpt("list-families").hasArg().argName("LicenseFilter")
+ .desc("List the defined license families (default is NONE). Valid options are: " + asString(LicenseFilter.values()))
+ .converter(s -> LicenseFilter.valueOf(s.toUpperCase()))
+ .build();
- private static final String LOG_LEVEL = "log-level";
- private static final String DRY_RUN = "dry-run";
+ /**
+ * Specify the log level for output
+ * @since 0.16.0
+ */
+ static final Option LOG_LEVEL = Option.builder().longOpt("log-level")
+ .hasArgs().argName("LogLevel")
+ .desc("sets the log level.")
+ .converter(s -> Log.Level.valueOf(s.toUpperCase()))
+ .build();
+
+ /**
+ * Do not update files.
+ * @since 0.16.0
+ */
+ static final Option DRY_RUN = Option.builder().longOpt("dry-run")
+ .desc("If set do not update the files but generate the reports.")
+ .build();
/**
* Set unstyled XML output
*/
- private static final String XML = "x";
+ static final Option XML = new Option("x", "xml", false, "Output the report in raw XML format. Not compatible with -s");
+ /**
+ * Specify the processing of ARCHIVE files.
+ * @since 0.17.0
+ */
+ static final Option ARCHIVE = Option.builder().longOpt("archive").hasArg().argName("ProcessingType")
+ .desc(format("Specifies the level of detail in ARCHIVE reporting. (default is %s)",
+ ReportConfiguration.Processing.NOTIFICATION))
+ .converter(s -> ReportConfiguration.Processing.valueOf(s.toUpperCase()))
+ .build();
+
+ private static String asString(Object[] args) {
+ return Arrays.stream(args).map(Object::toString).collect(Collectors.joining(", "));
+ }
/**
* Processes the command line and builds a configuration and executes the
* report.
- *
+ *
* @param args the arguments.
* @throws Exception on error.
*/
@@ -140,7 +272,8 @@
/**
* Parses the standard options to create a ReportConfiguraton.
- * @param args the arguments to parse
+ *
+ * @param args the arguments to parse
* @param helpCmd the help command to run when necessary.
* @return a ReportConfiguration or null if Help was printed.
* @throws IOException on error.
@@ -148,12 +281,13 @@
public static ReportConfiguration parseCommands(String[] args, Consumer<Options> helpCmd) throws IOException {
return parseCommands(args, helpCmd, false);
}
-
+
/**
* Parses the standard options to create a ReportConfiguraton.
- * @param args the arguments to parse
+ *
+ * @param args the arguments to parse
* @param helpCmd the help command to run when necessary.
- * @param noArgs If true then the commands do not need extra arguments
+ * @param noArgs If true then the commands do not need extra arguments
* @return a ReportConfiguration or null if Help was printed.
* @throws IOException on error.
*/
@@ -167,16 +301,14 @@
DefaultLog.INSTANCE.error("Please use the \"--help\" option to see a list of valid commands and options");
System.exit(1);
return null; // dummy return (won't be reached) to avoid Eclipse complaint about possible NPE
- // for "cl"
+ // for "cl"
}
if (cl.hasOption(LOG_LEVEL)) {
try {
- Log.Level level = Log.Level.valueOf(cl.getOptionValue(LOG_LEVEL).toUpperCase());
- DefaultLog.INSTANCE.setLevel(level);
- } catch (IllegalArgumentException e) {
- DefaultLog.INSTANCE.warn(String.format("Invalid Log Level (%s) specified.", cl.getOptionValue(LOG_LEVEL)));
- DefaultLog.INSTANCE.warn(String.format("Log level set at: %s", DefaultLog.INSTANCE.getLevel()));
+ DefaultLog.INSTANCE.setLevel(cl.getParsedOptionValue(LOG_LEVEL));
+ } catch (ParseException e) {
+ logParseException(e, LOG_LEVEL, cl, DefaultLog.INSTANCE.getLevel());
}
}
if (cl.hasOption(HELP)) {
@@ -191,34 +323,14 @@
return null;
}
} else {
- args = new String[] {null};
+ args = new String[]{null};
}
-/* ReportConfiguration configuration = createConfiguration(args[0], cl);
- configuration.validate(DefaultLog.INSTANCE::error);
+ return createConfiguration(args[0], cl);
+ }
- boolean dryRun = false;
-
- if (cl.hasOption(LIST_FAMILIES)) {
- LicenseFilter f = LicenseFilter.fromText(cl.getOptionValue(LIST_FAMILIES));
- if (f != LicenseFilter.none) {
- dryRun = true;
- Reporter.listLicenseFamilies(configuration, f);
- }
- }
- if (cl.hasOption(LIST_LICENSES)) {
- LicenseFilter f = LicenseFilter.fromText(cl.getOptionValue(LIST_LICENSES));
- if (f != LicenseFilter.none) {
- dryRun = true;
- Reporter.listLicenses(configuration, f);
- }
- }
-
- if (!dryRun) {
- new Reporter(configuration).output();
- }
- }
-*/ ReportConfiguration configuration = createConfiguration(args[0], cl);
- return configuration;
+ private static void logParseException(ParseException e, Option opt, CommandLine cl, Object dflt) {
+ DefaultLog.INSTANCE.warn(format("Invalid %s specified: %s ", opt.getOpt(), cl.getOptionValue(opt)));
+ DefaultLog.INSTANCE.warn(format("%s set to: %s", opt.getOpt(), dflt));
}
static ReportConfiguration createConfiguration(String baseDirectory, CommandLine cl) throws IOException {
@@ -226,24 +338,44 @@
configuration.setDryRun(cl.hasOption(DRY_RUN));
if (cl.hasOption(LIST_FAMILIES)) {
- configuration.listFamilies( LicenseFilter.valueOf(cl.getOptionValue(LIST_FAMILIES).toLowerCase()));
+ try {
+ configuration.listFamilies(cl.getParsedOptionValue(LIST_FAMILIES));
+ } catch (ParseException e) {
+ logParseException(e, LIST_FAMILIES, cl, Defaults.LIST_FAMILIES);
+ }
}
-
+
if (cl.hasOption(LIST_LICENSES)) {
- configuration.listFamilies( LicenseFilter.valueOf(cl.getOptionValue(LIST_LICENSES).toLowerCase()));
+ try {
+ configuration.listFamilies(cl.getParsedOptionValue(LIST_LICENSES));
+ } catch (ParseException e) {
+ logParseException(e, LIST_LICENSES, cl, Defaults.LIST_LICENSES);
+ }
}
-
- if (cl.hasOption('o')) {
- configuration.setOut(new File(cl.getOptionValue('o')));
+
+ if (cl.hasOption(ARCHIVE)) {
+ try {
+ configuration.setArchiveProcessing(cl.getParsedOptionValue(ARCHIVE));
+ } catch (ParseException e) {
+ logParseException(e, ARCHIVE, cl, Defaults.ARCHIVE_PROCESSING);
+ }
+ }
+
+ if (cl.hasOption(OUT)) {
+ try {
+ configuration.setOut((File) cl.getParsedOptionValue(OUT));
+ } catch (ParseException e) {
+ logParseException(e, OUT, cl, "System.out");
+ }
}
if (cl.hasOption(SCAN_HIDDEN_DIRECTORIES)) {
- configuration.setDirectoriesToIgnore(null);
+ configuration.setDirectoriesToIgnore(FalseFileFilter.FALSE);
}
- if (cl.hasOption('a') || cl.hasOption('A')) {
- configuration.setAddLicenseHeaders(cl.hasOption('f') ? AddLicenseHeaders.FORCED : AddLicenseHeaders.TRUE);
- configuration.setCopyrightMessage(cl.getOptionValue("c"));
+ if (ADD.getSelected() != null) {
+ configuration.setAddLicenseHeaders(cl.hasOption(FORCE) ? AddLicenseHeaders.FORCED : AddLicenseHeaders.TRUE);
+ configuration.setCopyrightMessage(cl.getOptionValue(COPYRIGHT));
}
if (cl.hasOption(EXCLUDE_CLI)) {
@@ -271,14 +403,12 @@
DefaultLog.INSTANCE.error("Please specify a single stylesheet");
System.exit(1);
}
- IOSupplier<InputStream> ioSupplier = null;
URL url = Report.class.getClassLoader().getResource(String.format("org/apache/rat/%s.xsl", style[0]));
- if (url == null) {
- ioSupplier = () -> Files.newInputStream(Paths.get(style[0]));
- } else {
- ioSupplier = url::openStream;
- }
+
+ IOSupplier<InputStream> ioSupplier = (url == null) ?
+ () -> Files.newInputStream(Paths.get(style[0])) :
+ url::openStream;
configuration.setStyleSheet(ioSupplier);
}
}
@@ -299,10 +429,10 @@
}
return configuration;
}
-
+
/**
* Creates a filename filter from patterns to exclude.
- *
+ *
* @param excludes the list of patterns to exclude.
* @return the FilenameFilter tht excludes the patterns
*/
@@ -332,101 +462,63 @@
}
static Options buildOptions() {
- String licFilterValues = Arrays.stream(LicenseFilter.values()).map(LicenseFilter::name).collect(Collectors.joining(", "));
-
- Options opts = new Options()
- .addOption(Option.builder().longOpt(DRY_RUN)
- .desc("If set do not update the files but generate the reports.")
- .build())
- .addOption(
- Option.builder().hasArg(true).longOpt(LIST_FAMILIES)
- .desc("List the defined license families (default is none). Valid options are: "+licFilterValues+".")
- .build())
- .addOption(
- Option.builder().hasArg(true).longOpt(LIST_LICENSES)
- .desc("List the defined licenses (default is none). Valid options are: "+licFilterValues+".")
- .build())
-
- .addOption(new Option(HELP, "help", false, "Print help for the RAT command line interface and exit."));
-
- Option out = new Option("o", "out", true,
- "Define the output file where to write a report to (default is System.out).");
- opts.addOption(out);
-
- String defaultHandlingText = " By default all approved default licenses are used";
- Option noDefaults = new Option(null, NO_DEFAULTS, false, "Ignore default configuration." + defaultHandlingText);
- opts.addOption(noDefaults);
-
- opts.addOption(null, LICENSES, true, "File names or URLs for license definitions");
- opts.addOption(null, SCAN_HIDDEN_DIRECTORIES, false, "Scan hidden directories");
-
- OptionGroup addLicenseGroup = new OptionGroup();
- // RAT-85/RAT-203: Deprecated! added only for convenience and for backwards
- // compatibility
- Option addLicence = new Option(ADD_OLD, false, "(deprecated) Add the default license header to any file with an unknown license. Use '-A' or ---addLicense instead.");
- addLicenseGroup.addOption(addLicence);
- Option addLicense = new Option(ADD, "addLicense", false, "Add the default license header to any file with an unknown license that is not in the exclusion list. "
- + "By default new files will be created with the license header, "
- + "to force the modification of existing files use the --force option.");
- addLicenseGroup.addOption(addLicense);
- opts.addOptionGroup(addLicenseGroup);
-
- Option write = new Option(FORCE, "force", false,
- "Forces any changes in files to be written directly to the source files (i.e. new files are not created).");
- opts.addOption(write);
-
- Option copyright = new Option(COPYRIGHT, "copyright", true,
- "The copyright message to use in the license headers, usually in the form of \"Copyright 2008 Foo\"");
- opts.addOption(copyright);
-
- final Option exclude = Option.builder(EXCLUDE_CLI).argName("expression").longOpt("exclude").hasArgs()
- .desc("Excludes files matching wildcard <expression>. "
- + "Note that --dir is required when using this parameter. " + "Allows multiple arguments.")
- .build();
- opts.addOption(exclude);
-
- final Option excludeFile = Option.builder(EXCLUDE_FILE_CLI).argName("fileName").longOpt("exclude-file")
- .hasArgs().desc("Excludes files matching regular expression in <file> "
- + "Note that --dir is required when using this parameter. ")
- .build();
- opts.addOption(excludeFile);
-
- Option dir = new Option("d", "dir", false, "Used to indicate source when using --exclude");
- opts.addOption(dir);
-
- opts.addOption( Option.builder().argName("level").longOpt(LOG_LEVEL)
- .hasArgs().desc("sets the log level. Valid options are: DEBUG, INFO, WARN, ERROR, OFF")
- .build() );
-
- OptionGroup outputType = new OptionGroup();
-
- Option xml = new Option(XML, "xml", false, "Output the report in raw XML format. Not compatible with -s");
- outputType.addOption(xml);
-
- Option xslt = new Option(STYLESHEET_CLI, "stylesheet", true,
- "XSLT stylesheet to use when creating the report. Not compatible with -x. Either an external xsl file may be specified or one of the internal named sheets: plain-rat (default), missing-headers, or unapproved-licenses");
- outputType.addOption(xslt);
- opts.addOptionGroup(outputType);
-
-
-
- return opts;
+ return new Options()
+ .addOption(ARCHIVE)
+ .addOption(DRY_RUN)
+ .addOption(LIST_FAMILIES)
+ .addOption(LIST_LICENSES)
+ .addOption(HELP)
+ .addOption(OUT)
+ .addOption(NO_DEFAULTS)
+ .addOption(LICENSES)
+ .addOption(SCAN_HIDDEN_DIRECTORIES)
+ .addOptionGroup(ADD)
+ .addOption(FORCE)
+ .addOption(COPYRIGHT)
+ .addOption(EXCLUDE_CLI)
+ .addOption(EXCLUDE_FILE_CLI)
+ .addOption(DIR)
+ .addOption(LOG_LEVEL)
+ .addOptionGroup(new OptionGroup()
+ .addOption(XML).addOption(STYLESHEET_CLI));
}
private static void printUsage(Options opts) {
- HelpFormatter f = new HelpFormatter();
- f.setOptionComparator(new OptionComparator());
- String header = System.lineSeparator()+"Available options";
+ printUsage(new PrintWriter(System.out), opts);
+ }
- String footer = String.format("%nNOTE:%nRat is really little more than a grep ATM%n"
- + "Rat is also rather memory hungry ATM%n" + "Rat is very basic ATM%n"
- + "Rat highlights possible issues%n" + "Rat reports require interpretation%n"
- + "Rat often requires some tuning before it runs well against a project%n"
- + "Rat relies on heuristics: it may miss issues%n");
+ protected static String createPadding(int len) {
+ char[] padding = new char[len];
+ Arrays.fill(padding, ' ');
+ return new String(padding);
+ }
- f.printHelp("java -jar apache-rat/target/apache-rat-CURRENT-VERSION.jar [options] [DIR|TARBALL]", header, opts,
- footer, false);
- System.exit(0);
+ static String header(String txt) {
+ return String.format("%n====== %s ======%n", WordUtils.capitalizeFully(txt));
+ }
+ static void printUsage(PrintWriter writer, Options opts) {
+
+ HelpFormatter helpFormatter = new HelpFormatter();
+ helpFormatter.setWidth(130);
+ helpFormatter.setOptionComparator(new OptionComparator());
+ String syntax = "java -jar apache-rat/target/apache-rat-CURRENT-VERSION.jar [options] [DIR|TARBALL]";
+ helpFormatter.printHelp(writer, helpFormatter.getWidth(), syntax, header("Available options"), opts,
+ helpFormatter.getLeftPadding(), helpFormatter.getDescPadding(),
+ header("Argument Types"), false);
+
+ String argumentPadding = createPadding(helpFormatter.getLeftPadding() + 5);
+ for (Map.Entry<String, Supplier<String>> argInfo : ARGUMENT_TYPES.entrySet()) {
+ writer.format("\n<%s>\n", argInfo.getKey());
+ helpFormatter.printWrapped(writer, helpFormatter.getWidth(), helpFormatter.getLeftPadding() + 10,
+ argumentPadding + argInfo.getValue().get());
+ }
+ writer.println(header("Notes"));
+
+ int idx = 1;
+ for (String note : NOTES) {
+ writer.format("%d. %s%n", idx++, note);
+ }
+ writer.flush();
}
private Report() {
@@ -436,40 +528,34 @@
/**
* Creates an IReportable object from the directory name and ReportConfiguration
* object.
- *
+ *
* @param baseDirectory the directory that contains the files to report on.
- * @param config the ReportConfiguration.
+ * @param config the ReportConfiguration.
* @return the IReportable instance containing the files.
*/
private static IReportable getDirectory(String baseDirectory, ReportConfiguration config) {
- try (PrintStream out = new PrintStream(config.getOutput().get())) {
- File base = new File(baseDirectory);
-
- if (!base.exists()) {
- config.getLog().log(Level.ERROR, "Directory '"+baseDirectory+"' does not exist");
- return null;
- }
+ File base = new File(baseDirectory);
- if (base.isDirectory()) {
- return new DirectoryWalker(base, config.getFilesToIgnore(), config.getDirectoriesToIgnore());
- }
-
- try {
- return new ArchiveWalker(base, config.getFilesToIgnore());
- } catch (IOException ex) {
- config.getLog().log(Level.ERROR, "file '"+baseDirectory+"' is not valid gzip data.");
- return null;
- }
- } catch (IOException e) {
- throw new ConfigurationException("Error opening output", e);
+ if (!base.exists()) {
+ config.getLog().log(Level.ERROR, "Directory '" + baseDirectory + "' does not exist");
+ return null;
}
+
+ Document doc = new FileDocument(base);
+ if (base.isDirectory()) {
+ return new DirectoryWalker(config, doc);
+ }
+
+ return new ArchiveWalker(config, doc);
}
/**
* This class implements the {@code Comparator} interface for comparing Options.
*/
public static class OptionComparator implements Comparator<Option>, Serializable {
- /** The serial version UID. */
+ /**
+ * The serial version UID.
+ */
private static final long serialVersionUID = 5305467873966684014L;
private String getKey(Option opt) {
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 dee2915..4b7c1b1 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
@@ -57,6 +57,17 @@
* configuration and invoke the {@link Reporter}.
*/
public class ReportConfiguration {
+
+ public enum Processing {NOTIFICATION("List file as present"), PRESENCE("List any licenses found"), ABSENCE("List licenses found and any unknown licences");
+
+ private final String description;
+ Processing(String description) {
+ this.description = description;
+ }
+ public String desc() { return description; }
+ }
+
+
private final ReportingSet<ILicenseFamily> families;
private final ReportingSet<ILicense> licenses;
private final SortedSet<String> approvedLicenseCategories;
@@ -74,7 +85,7 @@
private LicenseFilter listFamilies;
private LicenseFilter listLicenses;
private boolean dryRun;
-
+ private Processing archiveProcessing;
/**
* Constructor
@@ -89,11 +100,27 @@
approvedLicenseCategories = new TreeSet<>();
removedLicenseCategories = new TreeSet<>();
styleReport = true;
- listFamilies = LicenseFilter.NONE;
- listLicenses = LicenseFilter.NONE;
+ listFamilies = Defaults.LIST_FAMILIES;
+ listLicenses = Defaults.LIST_LICENSES;
dryRun = false;
}
-
+
+ /**
+ * Retrieves the archive processing type.
+ * @return The archive processing type.
+ */
+ public Processing getArchiveProcessing() {
+ return archiveProcessing == null ? Defaults.ARCHIVE_PROCESSING : archiveProcessing;
+ }
+
+ /**
+ * Sets the archive processing type. If not set will default to NOTIFICATION.
+ * @param archiveProcessing the type of processing archives should have.
+ */
+ public void setArchiveProcessing(Processing archiveProcessing) {
+ this.archiveProcessing = archiveProcessing;
+ }
+
/**
* Retrieves the Log that was provided in the constructor.
* @return the Log for the system.
@@ -168,40 +195,55 @@
/**
* Returns the state of the dry run flag.
- * @return the stae of the dry run flag.
+ * @return the state of the dry run flag.
*/
public boolean isDryRun() {
return dryRun;
}
/**
- * @return The filename filter for the potential input files.
+ * Gets the file name filter for files to ignore.
+ * @return The filename filter that identifies files to ignore.
*/
public FilenameFilter getFilesToIgnore() {
- return filesToIgnore;
+ return filesToIgnore == null ? Defaults.FILES_TO_IGNORE : filesToIgnore;
}
/**
+ * Sets the files name filter for files to ignore.
+ * If not set or set to {@code null} uses the Default.FILES_TO_IGNORE value.
* @param filesToIgnore the filename filter to filter the input files.
+ * @see Defaults#FILES_TO_IGNORE
*/
public void setFilesToIgnore(FilenameFilter filesToIgnore) {
this.filesToIgnore = filesToIgnore;
}
+ /**
+ * Gets the directories filter.
+ * @return the directories filter.
+ */
public IOFileFilter getDirectoriesToIgnore() {
- return directoriesToIgnore;
+ return directoriesToIgnore == null ? Defaults.DIRECTORIES_TO_IGNORE : directoriesToIgnore;
}
+ /**
+ * Sets the directories to ignore.
+ * If {@code directoriesToIgnore} is null removes all directories to ignore.
+ * If not set {@code Defaults.DIRECTORIES_TO_IGNORE} is used.
+ * @param directoriesToIgnore the filter that defines the directories to ignore.
+ * @see Defaults#DIRECTORIES_TO_IGNORE
+ */
public void setDirectoriesToIgnore(IOFileFilter directoriesToIgnore) {
- if (directoriesToIgnore == null) {
- this.directoriesToIgnore = FalseFileFilter.FALSE;
- } else {
- this.directoriesToIgnore = directoriesToIgnore;
- }
+ this.directoriesToIgnore = directoriesToIgnore == null ? FalseFileFilter.FALSE : directoriesToIgnore;
}
+ /**
+ * Adds a directory filter to the directories to ignore.
+ * @param directoryToIgnore the directory filter to add.
+ */
public void addDirectoryToIgnore(IOFileFilter directoryToIgnore) {
- this.directoriesToIgnore = this.directoriesToIgnore.and(directoryToIgnore);
+ this.directoriesToIgnore = this.directoriesToIgnore.or(directoryToIgnore);
}
/**
@@ -245,8 +287,6 @@
* @param defaults The defaults to set.
*/
public void setFrom(Defaults defaults) {
- setFilesToIgnore(Defaults.getFilesToIgnore());
- setDirectoriesToIgnore(Defaults.getDirectoriesToIgnore());
addLicensesIfNotPresent(defaults.getLicenses(LicenseFilter.ALL));
addApprovedLicenseCategories(defaults.getLicenseIds(LicenseFilter.APPROVED));
if (isStyleReport() && getStyleSheet() == null) {
diff --git a/apache-rat-core/src/main/java/org/apache/rat/analysis/DefaultAnalyserFactory.java b/apache-rat-core/src/main/java/org/apache/rat/analysis/DefaultAnalyserFactory.java
index 141de2a..416bfd4 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/analysis/DefaultAnalyserFactory.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/analysis/DefaultAnalyserFactory.java
@@ -19,13 +19,18 @@
package org.apache.rat.analysis;
import java.util.Collection;
+import java.util.Set;
+import java.util.function.Predicate;
import org.apache.rat.ConfigurationException;
+import org.apache.rat.ReportConfiguration;
import org.apache.rat.api.Document;
+import org.apache.rat.api.RatException;
import org.apache.rat.document.IDocumentAnalyser;
import org.apache.rat.document.RatDocumentAnalysisException;
import org.apache.rat.license.ILicense;
-import org.apache.rat.utils.Log;
+import org.apache.rat.license.LicenseSetFactory;
+import org.apache.rat.walker.ArchiveWalker;
/**
* Creates default analysers.
@@ -35,58 +40,71 @@
/**
* Creates a DocumentAnalyser from a collection of ILicenses.
*
- * @param log The Log to use for logging.
- * @param licenses The licenses to use in the Analyser.
+ * @param configuration the ReportConfiguration
* @return A document analyser that uses the provides licenses.
*/
- public static IDocumentAnalyser createDefaultAnalyser(Log log, Collection<ILicense> licenses) {
+ public static IDocumentAnalyser createDefaultAnalyser(final ReportConfiguration configuration) {
+ Set<ILicense> licenses = configuration.getLicenses(LicenseSetFactory.LicenseFilter.ALL);
if (licenses.isEmpty()) {
throw new ConfigurationException("At least one license must be defined");
}
- log.debug("Licenses in Test");
- licenses.forEach(log::debug);
- return new DefaultAnalyser(log, licenses);
+ configuration.getLog().debug("Licenses in Test");
+ licenses.forEach(configuration.getLog()::debug);
+ return new DefaultAnalyser(configuration, licenses);
}
/**
- * A DocumentAnalyser for the license
+ * A DocumentAnalyser a collection of licenses
*/
private final static class DefaultAnalyser implements IDocumentAnalyser {
/** The licenses to analyze */
private final Collection<ILicense> licenses;
- /** The log to use */
- private final Log log;
+
+ /** the Report Configuration */
+ private final ReportConfiguration configuration;
/**
* Constructs a DocumentAnalyser for the specified license.
- * @param log the Log to use
+ * @param config the ReportConfiguration
* @param licenses The licenses to analyse
*/
- public DefaultAnalyser(final Log log, final Collection<ILicense> licenses) {
+ public DefaultAnalyser(ReportConfiguration config, final Collection<ILicense> licenses) {
this.licenses = licenses;
- this.log = log;
+ this.configuration = config;
}
@Override
public void analyse(Document document) throws RatDocumentAnalysisException {
- TikaProcessor.process(log, document);
+ TikaProcessor.process(configuration.getLog(), document);
switch (document.getMetaData().getDocumentType()) {
case STANDARD:
- DocumentHeaderAnalyser analyser = new DocumentHeaderAnalyser(log, licenses);
- analyser.analyse(document);
- case NOTICE:
+ new DocumentHeaderAnalyser(configuration.getLog(), licenses).analyse(document);
+ break;
case ARCHIVE:
+ if (configuration.getArchiveProcessing() != ReportConfiguration.Processing.NOTIFICATION) {
+ ArchiveWalker archiveWalker = new ArchiveWalker(configuration, document);
+ Predicate<ILicense> filter = configuration.getArchiveProcessing() == ReportConfiguration.Processing.ABSENCE ?
+ l -> Boolean.TRUE : lic -> !lic.getLicenseFamily().equals(UnknownLicense.INSTANCE.getLicenseFamily());
+ try {
+ Collection<Document> docs = archiveWalker.getDocuments(configuration.getLog());
+ for (Document doc : docs) {
+ analyse(doc);
+ doc.getMetaData().licenses().filter(filter).forEach(lic -> document.getMetaData().reportOnLicense(lic));
+ }
+ } catch (RatException e) {
+ throw new RatDocumentAnalysisException(e);
+ }
+ }
+ break;
+ case NOTICE:
case BINARY:
case UNKNOWN:
default:
break;
}
-
-
-
}
}
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/analysis/DocumentHeaderAnalyser.java b/apache-rat-core/src/main/java/org/apache/rat/analysis/DocumentHeaderAnalyser.java
index 7ff1f26..31edfa0 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/analysis/DocumentHeaderAnalyser.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/analysis/DocumentHeaderAnalyser.java
@@ -42,7 +42,8 @@
/**
* Constructs the HeaderAnalyser for the specific license.
*
- * @param license The license to analyse
+ * @param log The log to write message to.
+ * @param licenses The licenses to analyse
*/
public DocumentHeaderAnalyser(final Log log, final Collection<ILicense> licenses) {
super();
diff --git a/apache-rat-core/src/main/java/org/apache/rat/api/Document.java b/apache-rat-core/src/main/java/org/apache/rat/api/Document.java
index 5d4467d..c2d861a 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/api/Document.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/api/Document.java
@@ -21,17 +21,21 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.SortedSet;
import org.apache.rat.document.CompositeDocumentException;
/**
* The representation of a document being scanned.
*/
-public interface Document {
+public abstract class Document implements Comparable<Document> {
+
/**
* An enumeraton of document types.
*/
- enum Type {
+ public enum Type {
/** A generated document. */
GENERATED,
/** An unknown document type. */
@@ -46,10 +50,50 @@
STANDARD;;
}
+ private final MetaData metaData;
+ private final String name;
+
+ /**
+ * Creates an instance.
+ * @param name the name of the resource.
+ */
+ protected Document(String name) {
+ this.name = name;
+ this.metaData = new MetaData();
+ }
+
/**
* @return the name of the current document.
*/
- String getName();
+ public final String getName() {
+ return name;
+ }
+
+ @Override
+ public int compareTo(Document doc) {
+ return getPath().compareTo(doc.getPath());
+ }
+
+ @Override
+ public int hashCode() {
+ return getPath().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || ! (obj instanceof Document)) {
+ return false;
+ }
+ return getPath().equals(((Document)obj).getPath());
+ }
+
+ /**
+ * Get the path that identifies the document.
+ * @return
+ */
+ public Path getPath() {
+ return Paths.get(getName());
+ }
/**
* Reads the contents of this document.
@@ -59,7 +103,7 @@
* @throws CompositeDocumentException if this document can only be read as a
* composite archive
*/
- Reader reader() throws IOException;
+ public abstract Reader reader() throws IOException;
/**
* Streams the document's contents.
@@ -67,19 +111,38 @@
* @return a non null input stream of the document.
* @throws IOException when stream could not be opened
*/
- InputStream inputStream() throws IOException;
+ public abstract InputStream inputStream() throws IOException;
/**
* Gets data describing this resource.
*
* @return a non null MetaData object.
*/
- MetaData getMetaData();
+ public final MetaData getMetaData() {
+ return metaData;
+ }
/**
- * Tests if this a composite document.
- *
- * @return true if composite, false otherwise
+ * Representations suitable for logging.
+ * @return a <code>String</code> representation
+ * of this object.
*/
- boolean isComposite();
+ @Override
+ public String toString()
+ {
+ return String.format("%s( name = %s metaData = %s )", this.getClass().getSimpleName(), getName(), getMetaData());
+ }
+
+ /**
+ * Determines if this Document is a directory type.
+ * @return {@code true} if this is a directory.
+ */
+ public abstract boolean isDirectory();
+
+ /**
+ * Gets a sorted set of Documents that are children of this document.
+ * @return A sorted set of child Documents. May be empty
+ */
+ public abstract SortedSet<Document> listChildren();
+
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/impl/AbstractMonolithicDocument.java b/apache-rat-core/src/main/java/org/apache/rat/document/impl/AbstractMonolithicDocument.java
deleted file mode 100644
index 302e372..0000000
--- a/apache-rat-core/src/main/java/org/apache/rat/document/impl/AbstractMonolithicDocument.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- */
-package org.apache.rat.document.impl;
-
-import org.apache.rat.api.Document;
-import org.apache.rat.api.MetaData;
-
-
-/**
- * Abstract base class for monolithic documents.
- */
-public abstract class AbstractMonolithicDocument implements Document {
- private final String name;
- private final MetaData metaData;
-
- public AbstractMonolithicDocument(String pName) {
- name = pName;
- this.metaData = new MetaData();
- }
-
- public boolean isComposite() {
- return false;
- }
-
- public String getName() {
- return name;
- }
-
- public MetaData getMetaData() {
- return metaData;
- }
-}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/impl/ArchiveEntryDocument.java b/apache-rat-core/src/main/java/org/apache/rat/document/impl/ArchiveEntryDocument.java
index f9b7f17..7450d1f 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/document/impl/ArchiveEntryDocument.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/document/impl/ArchiveEntryDocument.java
@@ -20,62 +20,56 @@
package org.apache.rat.document.impl;
import java.io.ByteArrayInputStream;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.SortedSet;
import org.apache.rat.api.Document;
-import org.apache.rat.api.MetaData;
-import org.apache.rat.api.RatException;
-public class ArchiveEntryDocument implements Document {
+/**
+ * A Document that wraps an Archive entry.
+ */
+public class ArchiveEntryDocument extends Document {
+ /** The contents of the entry */
private final byte[] contents;
- private final String name;
- private final MetaData metaData = new MetaData();
+ /** The path for the entry */
+ private final Path path;
- public ArchiveEntryDocument(File file, byte[] contents) throws RatException {
- super();
- name = DocumentImplUtils.toName(file);
+ /**
+ * Creates an Archive entry.
+ * @param path The path for the entry.
+ * @param contents the contents of the entry.
+ */
+ public ArchiveEntryDocument(Path path, byte[] contents) {
+ super(FileDocument.normalizeFileName(path.toFile()));
+ this.path = path;
this.contents = contents;
}
- public MetaData getMetaData() {
- return metaData;
- }
-
- public String getName() {
- return name;
- }
-
+ @Override
public InputStream inputStream() throws IOException {
return new ByteArrayInputStream(contents);
}
- public boolean isComposite() {
- return DocumentImplUtils.isZipStream(new ByteArrayInputStream(contents));
+ @Override
+ public boolean isDirectory() {
+ return false;
}
+ @Override
+ public SortedSet<Document> listChildren() {
+ return Collections.emptySortedSet();
+ }
+
+ @Override
public Reader reader() throws IOException {
return new InputStreamReader(new ByteArrayInputStream(contents), StandardCharsets.UTF_8);
}
-
-
- /**
- * Representations suitable for logging.
- * @return a <code>String</code> representation
- * of this object.
- */
- @Override
- public String toString()
- {
- return "TarEntryDocument ( "
- + "name = " + this.name + " "
- + "metaData = " + this.metaData + " "
- + " )";
- }
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/impl/DocumentImplUtils.java b/apache-rat-core/src/main/java/org/apache/rat/document/impl/DocumentImplUtils.java
deleted file mode 100644
index 5522e67..0000000
--- a/apache-rat-core/src/main/java/org/apache/rat/document/impl/DocumentImplUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- */
-package org.apache.rat.document.impl;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.ZipInputStream;
-
-import org.apache.commons.io.IOUtils;
-
-public class DocumentImplUtils {
-
- public final static String toName(File file) {
- String path = file.getPath();
- return path.replace('\\', '/');
- }
-
- public static final boolean isZipStream(InputStream stream) {
- ZipInputStream zip = new ZipInputStream(stream);
- try {
- zip.getNextEntry();
- return true;
- } catch (IOException e) {
- return false;
- } finally {
- IOUtils.closeQuietly(zip);
- }
- }
-
- public static final boolean isZip(File file) {
- try {
- return isZipStream(new FileInputStream(file));
- } catch (IOException e) {
- return false;
- }
- }
-
-}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/impl/FileDocument.java b/apache-rat-core/src/main/java/org/apache/rat/document/impl/FileDocument.java
index d6509bc..16d35b9 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/document/impl/FileDocument.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/document/impl/FileDocument.java
@@ -19,67 +19,71 @@
package org.apache.rat.document.impl;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
-import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.SortedSet;
+import java.util.TreeSet;
import org.apache.rat.api.Document;
-import org.apache.rat.api.MetaData;
/**
- * Document wrapping a file of undetermined composition.
- *
+ * Document wrapping a File object
*/
-public class FileDocument implements Document {
+public class FileDocument extends Document {
+ /** the wrapped file */
private final File file;
- private final String name;
- private final MetaData metaData = new MetaData();
-
+
+ /**
+ * Creates a File document.
+ * @param file the file to wrap.
+ */
public FileDocument(final File file) {
- super();
+ super(normalizeFileName(file));
this.file = file;
- name = DocumentImplUtils.toName(file);
}
- public boolean isComposite() {
- return DocumentImplUtils.isZip(file);
+ /**
+ * Normalizes a file name. Accounts for Windows to Unix conversion.
+ * @param file
+ * @return
+ */
+ public final static String normalizeFileName(File file) {
+ String path = file.getPath();
+ return path.replace('\\', '/');
+ }
+
+ @Override
+ public Path getPath() {
+ return file.toPath();
+ }
+
+ @Override
+ public boolean isDirectory() {
+ return file.isDirectory();
+ }
+
+ @Override
+ public SortedSet<Document> listChildren() {
+ if (isDirectory()) {
+ SortedSet<Document> result = new TreeSet<>();
+ Arrays.stream(file.listFiles()).map(f -> new FileDocument(f)).forEach(result::add);
+ return result;
+ }
+ return Collections.emptySortedSet();
}
public Reader reader() throws IOException {
return new FileReader(file);
}
- public String getName() {
- return name;
- }
-
- public MetaData getMetaData() {
- return metaData;
- }
-
public InputStream inputStream() throws IOException {
return Files.newInputStream(file.toPath());
}
-
- /**
- * Representations suitable for logging.
- * @return a <code>String</code> representation
- * of this object.
- */
- @Override
- public String toString()
- {
- return "FileDocument ( "
- + "file = " + this.file + " "
- + "name = " + this.name + " "
- + "metaData = " + this.metaData + " "
- + " )";
- }
-
-
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/impl/MonolithicFileDocument.java b/apache-rat-core/src/main/java/org/apache/rat/document/impl/MonolithicFileDocument.java
deleted file mode 100644
index e19c509..0000000
--- a/apache-rat-core/src/main/java/org/apache/rat/document/impl/MonolithicFileDocument.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- */
-package org.apache.rat.document.impl;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-
-import org.apache.rat.api.Document;
-
-
-public class MonolithicFileDocument extends AbstractMonolithicDocument {
- private static final String FILE_URL_PREFIX = "file";
-
- private final File file;
-
- /**
- * @return Creates and returns a new instance.
- *
- * @param url The document is read from the given URL.
- */
- public static Document newInstance(final URL url) {
- if (FILE_URL_PREFIX.equals(url.getProtocol())) {
- final File f = new File(url.getFile());
- return new MonolithicFileDocument(f);
- }
- return new AbstractMonolithicDocument(url.toExternalForm()){
- public Reader reader() throws IOException {
- return new InputStreamReader(inputStream(), StandardCharsets.UTF_8);
- }
-
- public InputStream inputStream() throws IOException {
- return url.openStream();
- }
- };
- }
-
- public MonolithicFileDocument(final File file) {
- super(DocumentImplUtils.toName(file));
- this.file = file;
- }
-
- public Reader reader() throws IOException {
- return new FileReader(file);
- }
-
- public InputStream inputStream() throws IOException {
- return Files.newInputStream(file.toPath());
- }
-}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/report/xml/XmlReportFactory.java b/apache-rat-core/src/main/java/org/apache/rat/report/xml/XmlReportFactory.java
index 1e5c17d..7f10204 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/report/xml/XmlReportFactory.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/report/xml/XmlReportFactory.java
@@ -67,8 +67,7 @@
reporters.add(new SimpleXmlClaimReporter(writer));
- final IDocumentAnalyser analyser =
- DefaultAnalyserFactory.createDefaultAnalyser(configuration.getLog(), configuration.getLicenses(LicenseFilter.ALL));
+ final IDocumentAnalyser analyser = DefaultAnalyserFactory.createDefaultAnalyser(configuration);
final DefaultPolicy policy = new DefaultPolicy(configuration.getLicenseFamilies(LicenseFilter.APPROVED));
final IDocumentAnalyser[] analysers = {analyser, policy};
diff --git a/apache-rat-core/src/main/java/org/apache/rat/report/xml/writer/impl/base/XmlWriter.java b/apache-rat-core/src/main/java/org/apache/rat/report/xml/writer/impl/base/XmlWriter.java
index 2495947..debd748 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/report/xml/writer/impl/base/XmlWriter.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/report/xml/writer/impl/base/XmlWriter.java
@@ -552,9 +552,20 @@
StringBuilder sb = new StringBuilder(content);
int found;
while (-1 != (found = sb.indexOf("]]>"))) {
- sb.replace(found, found + 3, "<!-- Rat removed CDATA closure here -->");
+ sb.replace(found, found + 3, "{rat:CDATA close}");
}
- writer.write(String.format("<![CDATA[ %s ]]>", sb.toString()));
+
+ writer.write("<![CDATA[ " );
+ for (int i=0;i<sb.length();i++) {
+ char c = sb.charAt(i);
+ if (isOutOfRange(c)) {
+ writer.write(String.format("\\u%X", (int)c));
+ } else {
+ writer.write(c);
+ }
+ }
+ writer.write(" ]]>");
+
inElement = false;
return this;
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java b/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
index d61f735..a2a25c3 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
@@ -19,36 +19,45 @@
package org.apache.rat.walker;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
-import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
-import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
-import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
-import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+import org.apache.commons.compress.archivers.ArchiveStreamFactory;
+import org.apache.commons.io.IOUtils;
+import org.apache.rat.ReportConfiguration;
import org.apache.rat.api.Document;
import org.apache.rat.api.RatException;
import org.apache.rat.document.impl.ArchiveEntryDocument;
+import org.apache.rat.document.impl.FileDocument;
import org.apache.rat.report.RatReport;
+import org.apache.rat.utils.Log;
/**
* Walks various kinds of archives files
*/
public class ArchiveWalker extends Walker {
+ private final Log log;
/**
* Constructs a walker.
- * @param file not null
- * @param filter filters input files (optional) null when no filtering should be performed
- * @throws FileNotFoundException in case of I/O errors.
+ * @param config the report configuration for this run.
+ * @param document the document to process.
*/
- public ArchiveWalker(final File file, final FilenameFilter filter) throws FileNotFoundException {
- super(file, filter);
+ public ArchiveWalker(final ReportConfiguration config, Document document) {
+ super(document, config.getFilesToIgnore());
+ this.log = config.getLog();
}
/**
@@ -59,57 +68,43 @@
*
*/
public void run(final RatReport report) throws RatException {
-
- try {
- ArchiveInputStream<? extends ArchiveEntry> input;
-
- /* I am really sad that classes aren't first-class objects in
- Java :'( */
- try {
- input = new TarArchiveInputStream(new GzipCompressorInputStream(Files.newInputStream(getBaseFile().toPath())));
- } catch (IOException e) {
- try {
- input = new TarArchiveInputStream(new BZip2CompressorInputStream(Files.newInputStream(getBaseFile().toPath())));
- } catch (IOException e2) {
- input = new ZipArchiveInputStream(Files.newInputStream(getBaseFile().toPath()));
- }
- }
-
- ArchiveEntry entry = input.getNextEntry();
- while (entry != null) {
- File f = new File(entry.getName());
- byte[] contents = new byte[(int) entry.getSize()];
- int offset = 0;
- int length = contents.length;
-
- while (offset < entry.getSize()) {
- int actualRead = input.read(contents, offset, length);
- length -= actualRead;
- offset += actualRead;
- }
-
- if (!entry.isDirectory() && isNotIgnored(f)) {
- report(report, contents, f);
- }
-
- entry = input.getNextEntry();
- }
-
- input.close();
- } catch (IOException e) {
- throw new RatException(e);
+ for (Document document : getDocuments(log)) {
+ report.report(document);
}
}
/**
- * Report on the given file.
- *
- * @param report the report to process the file with
- * @param file the file to be reported on
- * @throws RatException
+ * Creates an input stream from the Directory being walked.
+ * @return A buffered input stream reading the archive data.
+ * @throws IOException on error
*/
- private void report(final RatReport report, final byte[] contents, final File file) throws RatException {
- Document document = new ArchiveEntryDocument(file, contents);
- report.report(document);
+ private InputStream createInputStream() throws IOException {
+ return new BufferedInputStream(getDocument().inputStream());
+ }
+ /**
+ * Retrieves the documents from the archive.
+ * @param log The log to write messages to.
+ * @return A collection of documents that pass the file filter.
+ * @throws RatException on error.
+ */
+ public Collection<Document> getDocuments(Log log) throws RatException {
+ List<Document> result = new ArrayList<>();
+ try (ArchiveInputStream<? extends ArchiveEntry> input = new ArchiveStreamFactory().createArchiveInputStream(createInputStream())) {
+ ArchiveEntry entry = null;
+ while ((entry = input.getNextEntry()) != null) {
+ Path path = this.getDocument().getPath().resolve("#"+entry.getName());
+ if (!entry.isDirectory() && this.isNotIgnored(path) && input.canReadEntryData(entry)) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ IOUtils.copy(input,baos);
+ result.add(new ArchiveEntryDocument(path, baos.toByteArray()));
+ }
+ }
+ } catch (ArchiveException e) {
+ log.warn(String.format("Unable to process %s: %s", getDocument().getName(), e.getMessage()));
+ }
+ catch (IOException e) {
+ throw RatException.asRatException(e);
+ }
+ return result;
}
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/DirectoryWalker.java b/apache-rat-core/src/main/java/org/apache/rat/walker/DirectoryWalker.java
index e3cf3a7..f62d0c0 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/DirectoryWalker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/walker/DirectoryWalker.java
@@ -21,10 +21,15 @@
import java.io.File;
import java.io.FilenameFilter;
+import java.nio.file.Path;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.SortedSet;
import org.apache.commons.io.filefilter.FalseFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.rat.ReportConfiguration;
+import org.apache.rat.api.Document;
import org.apache.rat.api.RatException;
import org.apache.rat.document.impl.FileDocument;
import org.apache.rat.report.RatReport;
@@ -34,33 +39,30 @@
*/
public class DirectoryWalker extends Walker {
- private static final FileNameComparator COMPARATOR = new FileNameComparator();
-
+ /** The directories to ignore */
private final IOFileFilter directoriesToIgnore;
/**
- * Constructs a walker.
+ * Constructs a directory walker.
*
- * @param file the directory to walk (not null).
- * @param filesToIgnore filters input files (optional),
- * or null when no filtering should be performed
- * @param directoriesToIgnore filters directories (optional), or null when no filtering should be performed.
+ * @param config the report configuration for this run.
+ * @param document the document to process.
*/
- public DirectoryWalker(final File file, final FilenameFilter filesToIgnore, final IOFileFilter directoriesToIgnore) {
- super(file, filesToIgnore);
- this.directoriesToIgnore = directoriesToIgnore == null ? FalseFileFilter.FALSE : directoriesToIgnore;
+ public DirectoryWalker(final ReportConfiguration config, Document document) {
+ super(document, config.getFilesToIgnore());
+ this.directoriesToIgnore = config.getDirectoriesToIgnore();
}
/**
* Process a directory, restricted directories will be ignored.
*
* @param report The report to process the directory with
- * @param file the directory to process
+ * @param document the document to process.
* @throws RatException on error.
*/
- private void processDirectory(final RatReport report, final File file) throws RatException {
- if (!directoriesToIgnore.accept(file)) {
- process(report, file);
+ private void processDirectory(final RatReport report, Document document) throws RatException {
+ if (isNotIgnoredDirectory(document.getPath())) {
+ process(report, document);
}
}
@@ -72,41 +74,41 @@
* @throws RatException on error
*/
public void run(final RatReport report) throws RatException {
- process(report, getBaseFile());
+ process(report, getDocument());
}
/**
* Process a directory, ignoring any files/directories set to be ignored.
*
* @param report the report to use in processing
- * @param file the run the report against
+ * @param document the document to run the report against
* @throws RatException on error
*/
- protected void process(final RatReport report, final File file) throws RatException {
- final File[] files = file.listFiles();
- if (files != null) {
- Arrays.sort(files, COMPARATOR);
+ protected void process(final RatReport report, Document document) throws RatException {
+ final SortedSet<Document> documents = document.listChildren();
+ if (documents != null) {
// breadth first traversal
- processNonDirectories(report, files);
- processDirectories(report, files);
+ processNonDirectories(report, documents);
+ processDirectories(report, documents);
}
}
- private boolean isNotIgnoredDirectory(final File file) {
- return !directoriesToIgnore.accept(file.getParentFile(), file.getName());
+ /** test for directory that is not ignored */
+ private boolean isNotIgnoredDirectory(Path path) {
+ return !directoriesToIgnore.accept(path.getParent().toFile(), path.toString());
}
/**
* Process all directories in a set of file objects, ignoring any directories set to be ignored.
*
* @param report the report to use in processing
- * @param files the files to process (only directories will be processed)
+ * @param documents the documents to process (only directories will be processed)
* @throws RatException on error
*/
- private void processDirectories(final RatReport report, final File[] files) throws RatException {
- for (final File file : files) {
- if (file.isDirectory() && isNotIgnoredDirectory(file)) {
- processDirectory(report, file);
+ private void processDirectories(final RatReport report, final SortedSet<Document> documents) throws RatException {
+ for (final Document doc : documents) {
+ if (doc.isDirectory() && isNotIgnoredDirectory(doc.getPath())) {
+ processDirectory(report, doc);
}
}
}
@@ -115,13 +117,13 @@
* Process all files in a set of file objects, ignoring any files set to be ignored.
*
* @param report the report to use in processing
- * @param files the files to process (only files will be processed)
+ * @param documents the documents to process (only files will be processed)
* @throws RatException on error
*/
- private void processNonDirectories(final RatReport report, final File[] files) throws RatException {
- for (final File file : files) {
- if (!file.isDirectory() && isNotIgnored(file)) {
- report.report(new FileDocument(file));
+ private void processNonDirectories(final RatReport report, final SortedSet<Document> documents) throws RatException {
+ for (final Document doc : documents) {
+ if (!doc.isDirectory() && isNotIgnored(doc.getPath())) {
+ report.report(doc);
}
}
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/FileNameComparator.java b/apache-rat-core/src/main/java/org/apache/rat/walker/FileNameComparator.java
deleted file mode 100644
index c3ed803..0000000
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/FileNameComparator.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- */
-package org.apache.rat.walker;
-
-import java.io.File;
-import java.util.Comparator;
-
-class FileNameComparator implements Comparator<File> {
-
- public int compare(File firstFile, File secondFile) {
- int result = 0;
- if (firstFile == null) {
- if (secondFile != null) {
- result = 1;
- }
- } else {
- if (secondFile == null) {
- result = -1;
- } else {
- final String firstName = firstFile.getName();
- final String secondName = secondFile.getName();
- result = firstName.compareTo(secondName);
- }
- }
- return result;
- }
-
-}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/Walker.java b/apache-rat-core/src/main/java/org/apache/rat/walker/Walker.java
index abb8cae..b5f112e 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/Walker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/walker/Walker.java
@@ -20,41 +20,47 @@
package org.apache.rat.walker;
import org.apache.commons.io.filefilter.FalseFileFilter;
+import org.apache.rat.api.Document;
import org.apache.rat.report.IReportable;
import java.io.File;
import java.io.FilenameFilter;
+import java.nio.file.Path;
/**
* Abstract walker.
*/
public abstract class Walker implements IReportable {
- /** The file that this walker started at */
- private final File baseFile;
-
/** The file name filter that the walker is applying */
private final FilenameFilter filesToIgnore;
+ /** The document this walker is walking */
+ private final Document document;
- public Walker(final File file, final FilenameFilter filesToIgnore) {
- this.baseFile = file;
+ /**
+ * Creates the walker
+ * @param document The document the walker is walking.
+ * @param filesToIgnore the Files to ignore. If {@code null} no files are ignored.
+ */
+ protected Walker(final Document document, final FilenameFilter filesToIgnore) {
+ this.document = document;
this.filesToIgnore = filesToIgnore == null ? FalseFileFilter.FALSE : filesToIgnore;
}
/**
- * Retrieve the file from the constructor.
- * @return the file from the constructor.
+ * Retrieves the document from the constructor.
+ * @return the document from the constructor.
*/
- protected File getBaseFile() {
- return baseFile;
+ protected Document getDocument() {
+ return document;
}
/**
- * Test if the specified file should be ignored.
- * @param file the file to test.
- * @return {@code true} if the file should be ignored.
+ * Tests if the specified path should be ignored.
+ * @param path the Path to test
+ * @return {@code true} if the file should not be ignored.
*/
- protected final boolean isNotIgnored(final File file) {
- return !filesToIgnore.accept(file.getParentFile(), file.getName());
+ protected final boolean isNotIgnored(Path path) {
+ return !filesToIgnore.accept(path.getParent().toFile(), path.toString());
}
}
diff --git a/apache-rat-core/src/main/resources/org/apache/rat/plain-rat.xsl b/apache-rat-core/src/main/resources/org/apache/rat/plain-rat.xsl
index da01cbb..b9cb417 100644
--- a/apache-rat-core/src/main/resources/org/apache/rat/plain-rat.xsl
+++ b/apache-rat-core/src/main/resources/org/apache/rat/plain-rat.xsl
@@ -54,9 +54,10 @@
<xsl:if test="descendant::resource[@type='ARCHIVE']">
Archives:
<xsl:for-each select='descendant::resource[@type="ARCHIVE"]'>
- + <xsl:value-of select='@name'/>
- <xsl:text>
- </xsl:text>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select='@name'/>
+ <xsl:text>
+</xsl:text>
</xsl:for-each>
</xsl:if>
<xsl:text>
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 48e962a..27b3aea 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
@@ -44,9 +44,9 @@
import java.util.SortedSet;
import java.util.function.Function;
-import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.FalseFileFilter;
+import org.apache.commons.io.filefilter.OrFileFilter;
import org.apache.commons.io.function.IOSupplier;
import org.apache.rat.ReportConfiguration.NoCloseOutputStream;
import org.apache.rat.analysis.IHeaderMatcher;
@@ -189,10 +189,9 @@
@Test
public void filesToIgnoreTest() {
- assertThat(underTest.getFilesToIgnore()).isNull();
+ assertThat(underTest.getFilesToIgnore()).isExactlyInstanceOf(FalseFileFilter.class);
underTest.setFrom(Defaults.builder().build(DefaultLog.INSTANCE));
- assertThat(underTest.getFilesToIgnore()).isNotNull();
assertThat(underTest.getFilesToIgnore()).isExactlyInstanceOf(FalseFileFilter.class);
FilenameFilter filter = mock(FilenameFilter.class);
@@ -202,21 +201,37 @@
@Test
public void directoriesToIgnoreTest() {
- assertThat(underTest.getDirectoriesToIgnore()).isNull();
+ assertThat(underTest.getDirectoriesToIgnore()).isExactlyInstanceOf(NameBasedHiddenFileFilter.class);
underTest.setFrom(Defaults.builder().build(DefaultLog.INSTANCE));
- assertThat(underTest.getDirectoriesToIgnore()).isNotNull();
assertThat(underTest.getDirectoriesToIgnore()).isExactlyInstanceOf(NameBasedHiddenFileFilter.class);
underTest.setDirectoriesToIgnore(DirectoryFileFilter.DIRECTORY);
underTest.addDirectoryToIgnore(NameBasedHiddenFileFilter.HIDDEN);
- assertThat(underTest.getDirectoriesToIgnore()).isExactlyInstanceOf(AndFileFilter.class);
+ assertThat(underTest.getDirectoriesToIgnore()).isExactlyInstanceOf(OrFileFilter.class);
underTest.setDirectoriesToIgnore(null);
assertThat(underTest.getDirectoriesToIgnore()).isExactlyInstanceOf(FalseFileFilter.class);
}
@Test
+ public void archiveProcessingTest() {
+ assertThat(underTest.getArchiveProcessing()).isEqualTo(ReportConfiguration.Processing.NOTIFICATION);
+
+ underTest.setFrom(Defaults.builder().build(DefaultLog.INSTANCE));
+ assertThat(underTest.getArchiveProcessing()).isEqualTo(ReportConfiguration.Processing.NOTIFICATION);
+
+ underTest.setArchiveProcessing(ReportConfiguration.Processing.ABSENCE);
+ assertThat(underTest.getArchiveProcessing()).isEqualTo(ReportConfiguration.Processing.ABSENCE);
+
+ underTest.setArchiveProcessing(ReportConfiguration.Processing.PRESENCE);
+ assertThat(underTest.getArchiveProcessing()).isEqualTo(ReportConfiguration.Processing.PRESENCE);
+
+ underTest.setArchiveProcessing(null);
+ assertThat(underTest.getArchiveProcessing()).isEqualTo(ReportConfiguration.Processing.NOTIFICATION);
+ }
+
+ @Test
public void licenseFamiliesTest() {
assertThat(underTest.getLicenseFamilies(LicenseFilter.ALL)).isEmpty();
assertThat(underTest.getLicenseFamilies(LicenseFilter.APPROVED)).isEmpty();
diff --git a/apache-rat-core/src/test/java/org/apache/rat/ReportTest.java b/apache-rat-core/src/test/java/org/apache/rat/ReportTest.java
index 185848c..448f824 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/ReportTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/ReportTest.java
@@ -18,36 +18,37 @@
*/
package org.apache.rat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
-import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathFactory;
-
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.apache.rat.testhelpers.TextUtils;
-import org.apache.rat.testhelpers.XmlUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import org.w3c.dom.Document;
-import org.w3c.dom.NodeList;
public class ReportTest {
@TempDir
File tempDirectory;
-
+
+ private ReportConfiguration createConfig(String... args) throws IOException, ParseException {
+ CommandLine cl = new DefaultParser().parse(Report.buildOptions(), args);
+ return Report.createConfiguration("target/test-classes/elements", cl);
+ }
+
@Test
public void parseExclusionsForCLIUsage() {
final FilenameFilter filter = Report
@@ -66,7 +67,7 @@
@Test
public void testOutputOption() throws Exception {
File output = new File(tempDirectory, "test");
- CommandLine cl = new DefaultParser().parse(Report.buildOptions(), new String[] { "-o", output.getCanonicalPath()});
+ CommandLine cl = new DefaultParser().parse(Report.buildOptions(), new String[]{"-o", output.getCanonicalPath()});
ReportConfiguration config = Report.createConfiguration("target/test-classes/elements", cl);
new Reporter(config).output();
assertTrue(output.exists());
@@ -77,104 +78,52 @@
}
@Test
- public void testDefaultOutput() throws Exception {
- File output = new File(tempDirectory,"sysout");
- output.delete();
- PrintStream origin = System.out;
- try (PrintStream out = new PrintStream(output)){
- System.setOut(out);
- CommandLine cl = new DefaultParser().parse(Report.buildOptions(), new String[] {});
- ReportConfiguration config = Report.createConfiguration("target/test-classes/elements", cl);
- new Reporter(config).output();
- } finally {
- System.setOut(origin);
- }
- assertTrue(output.exists());
- String content = FileUtils.readFileToString(output, StandardCharsets.UTF_8);
- TextUtils.assertPatternInOutput("Notes: 2$", content);
- TextUtils.assertPatternInOutput("Binaries: 2$", content);
- TextUtils.assertPatternInOutput("Archives: 1$", content);
- TextUtils.assertPatternInOutput("Standards: 8$", content);
- TextUtils.assertPatternInOutput("Apache Licensed: 5$", content);
- TextUtils.assertPatternInOutput("Generated Documents: 1$", content);
- TextUtils.assertPatternInOutput("^2 Unknown Licenses", content);
- assertTrue(content.contains(" S target/test-classes/elements/ILoggerFactory.java"));
- assertTrue(content.contains(" B target/test-classes/elements/Image.png"));
- assertTrue(content.contains(" N target/test-classes/elements/LICENSE"));
- assertTrue(content.contains(" N target/test-classes/elements/NOTICE"));
- assertTrue(content.contains("!S target/test-classes/elements/Source.java"));
- assertTrue(content.contains(" S target/test-classes/elements/Text.txt"));
- assertTrue(content.contains(" S target/test-classes/elements/TextHttps.txt"));
- assertTrue(content.contains(" S target/test-classes/elements/Xml.xml"));
- assertTrue(content.contains(" S target/test-classes/elements/buildr.rb"));
- assertTrue(content.contains(" A target/test-classes/elements/dummy.jar"));
- assertTrue(content.contains("!S target/test-classes/elements/sub/Empty.txt"));
- assertTrue(content.contains(" S target/test-classes/elements/tri.txt"));
- assertTrue(content.contains(" G target/test-classes/elements/generated.txt"));
+ public void helpTest() {
+ Options opts = Report.buildOptions();
+ StringWriter out = new StringWriter();
+ Report.printUsage(new PrintWriter(out), opts);
+
+ String result = out.toString();
+ System.out.println(result);
+
+ TextUtils.assertContains("-a ", result);
+ TextUtils.assertContains("-A,--addLicense ", result);
+ TextUtils.assertContains("--archive <ProcessingType> ", result);
+ TextUtils.assertContains("-c,--copyright <arg> ", result);
+ TextUtils.assertContains("-d,--dir <DirOrArchive> ", result);
+ TextUtils.assertContains("--dry-run ", result);
+ TextUtils.assertContains("-e,--exclude <Expression> ", result);
+ TextUtils.assertContains("-E,--exclude-file <FileOrURI> ", result);
+ TextUtils.assertContains("-f,--force ", result);
+ TextUtils.assertContains("-h,--help ", result);
+ TextUtils.assertContains("--licenses <FileOrURI> ", result);
+ TextUtils.assertContains("--list-families <LicenseFilter> ", result);
+ TextUtils.assertContains("--list-licenses <LicenseFilter> ", result);
+ TextUtils.assertContains("--log-level <LogLevel> ", result);
+ TextUtils.assertContains("--no-default-licenses ", result);
+ TextUtils.assertContains("-o,--out <arg> ", result);
+ TextUtils.assertContains("-s,--stylesheet <StyleSheet> ", result);
+ TextUtils.assertContains("--scan-hidden-directories ", result);
+ TextUtils.assertContains("-x,--xml ", result);
+ }
+
+ private static String shortOpt(Option opt) {
+ return "-" + opt.getOpt();
+ }
+
+ private static String longOpt(Option opt) {
+ return "--" + opt.getLongOpt();
}
@Test
public void testXMLOutput() throws Exception {
- File output = new File(tempDirectory,"sysout");
- output.delete();
- PrintStream origin = System.out;
- try (PrintStream out = new PrintStream(output)){
- System.setOut(out);
- CommandLine cl = new DefaultParser().parse(Report.buildOptions(), new String[] { "-x" });
- ReportConfiguration config = Report.createConfiguration("target/test-classes/elements", cl);
- new Reporter(config).output();
- } finally {
- System.setOut(origin);
- }
- assertTrue(output.exists());
- Document doc = XmlUtils.toDom(new FileInputStream(output));
- XPath xPath = XPathFactory.newInstance().newXPath();
+ ReportConfiguration config = createConfig();
+ assertTrue(config.isStyleReport());
- NodeList nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@approval='false']");
- assertEquals(2, nodeList.getLength());
+ config = createConfig(shortOpt(Report.XML));
+ assertFalse(config.isStyleReport());
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='AL']");
- assertEquals(5, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='MIT']");
- assertEquals(1, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='BSD-3']");
- assertEquals(1, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='TMF']");
- assertEquals(1, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='?????']");
- assertEquals(2, nodeList.getLength());
-
- // GENERATED, UNKNOWN, ARCHIVE, NOTICE, BINARY, STANDARD
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='STANDARD']");
- assertEquals(8, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='ARCHIVE']");
- assertEquals(1, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='BINARY']");
- assertEquals(2, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='GENERATED']");
- assertEquals(1, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='UNKNOWN']");
- assertEquals(0, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='NOTICE']");
- assertEquals(2, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/sample");
- assertEquals(1, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='GENERATED']/license/notes");
- assertEquals(1, nodeList.getLength());
-
- nodeList = XmlUtils.getNodeList(doc, xPath,
- "/rat-report/resource[@name='target/test-classes/elements/Source.java']/sample");
- assertEquals(1, nodeList.getLength());
+ config = createConfig(longOpt(Report.XML));
+ assertFalse(config.isStyleReport());
}
}
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 7ca9b7d..160519c 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
@@ -24,13 +24,20 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.HiddenFileFilter;
import org.apache.rat.api.Document.Type;
+import org.apache.rat.document.impl.FileDocument;
import org.apache.rat.license.ILicenseFamily;
import org.apache.rat.test.utils.Resources;
import org.apache.rat.testhelpers.TextUtils;
@@ -38,6 +45,7 @@
import org.apache.rat.utils.DefaultLog;
import org.apache.rat.walker.DirectoryWalker;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
@@ -45,7 +53,123 @@
* Tests the output of the Reporter.
*/
public class ReporterTest {
+ @TempDir
+ File tempDirectory;
+ @Test
+ public void testOutputOption() throws Exception {
+ File output = new File(tempDirectory, "test");
+ CommandLine cl = new DefaultParser().parse(Report.buildOptions(), new String[] { "-o", output.getCanonicalPath()});
+ ReportConfiguration config = Report.createConfiguration("target/test-classes/elements", cl);
+ new Reporter(config).output();
+ assertTrue(output.exists());
+ String content = FileUtils.readFileToString(output, StandardCharsets.UTF_8);
+ assertTrue(content.contains("2 Unknown Licenses"));
+ assertTrue(content.contains("target/test-classes/elements/Source.java"));
+ assertTrue(content.contains("target/test-classes/elements/sub/Empty.txt"));
+ }
+
+ @Test
+ public void testDefaultOutput() throws Exception {
+ File output = new File(tempDirectory,"sysout");
+ output.delete();
+ PrintStream origin = System.out;
+ try (PrintStream out = new PrintStream(output)){
+ System.setOut(out);
+ CommandLine cl = new DefaultParser().parse(Report.buildOptions(), new String[] {});
+ ReportConfiguration config = Report.createConfiguration("target/test-classes/elements", cl);
+ new Reporter(config).output();
+ } finally {
+ System.setOut(origin);
+ }
+ assertTrue(output.exists());
+ String content = FileUtils.readFileToString(output, StandardCharsets.UTF_8);
+ TextUtils.assertPatternInTarget("Notes: 2$", content);
+ TextUtils.assertPatternInTarget("Binaries: 2$", content);
+ TextUtils.assertPatternInTarget("Archives: 1$", content);
+ TextUtils.assertPatternInTarget("Standards: 8$", content);
+ TextUtils.assertPatternInTarget("Apache Licensed: 5$", content);
+ TextUtils.assertPatternInTarget("Generated Documents: 1$", content);
+ TextUtils.assertPatternInTarget("^2 Unknown Licenses", content);
+ assertTrue(content.contains(" S target/test-classes/elements/ILoggerFactory.java"));
+ assertTrue(content.contains(" B target/test-classes/elements/Image.png"));
+ assertTrue(content.contains(" N target/test-classes/elements/LICENSE"));
+ assertTrue(content.contains(" N target/test-classes/elements/NOTICE"));
+ assertTrue(content.contains("!S target/test-classes/elements/Source.java"));
+ assertTrue(content.contains(" S target/test-classes/elements/Text.txt"));
+ assertTrue(content.contains(" S target/test-classes/elements/TextHttps.txt"));
+ assertTrue(content.contains(" S target/test-classes/elements/Xml.xml"));
+ assertTrue(content.contains(" S target/test-classes/elements/buildr.rb"));
+ assertTrue(content.contains(" A target/test-classes/elements/dummy.jar"));
+ assertTrue(content.contains("!S target/test-classes/elements/sub/Empty.txt"));
+ assertTrue(content.contains(" S target/test-classes/elements/tri.txt"));
+ assertTrue(content.contains(" G target/test-classes/elements/generated.txt"));
+ }
+
+ @Test
+ public void testXMLOutput() throws Exception {
+ File output = new File(tempDirectory,"sysout");
+ output.delete();
+ PrintStream origin = System.out;
+ try (PrintStream out = new PrintStream(output)){
+ System.setOut(out);
+ CommandLine cl = new DefaultParser().parse(Report.buildOptions(), new String[] { "-x" });
+ ReportConfiguration config = Report.createConfiguration("target/test-classes/elements", cl);
+ new Reporter(config).output();
+ } finally {
+ System.setOut(origin);
+ }
+ assertTrue(output.exists());
+ Document doc = XmlUtils.toDom(new FileInputStream(output));
+ XPath xPath = XPathFactory.newInstance().newXPath();
+
+ NodeList nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@approval='false']");
+ assertEquals(2, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='AL']");
+ assertEquals(5, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='MIT']");
+ assertEquals(1, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='BSD-3']");
+ assertEquals(1, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='TMF']");
+ assertEquals(1, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/license[@id='?????']");
+ assertEquals(2, nodeList.getLength());
+
+ // GENERATED, UNKNOWN, ARCHIVE, NOTICE, BINARY, STANDARD
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='STANDARD']");
+ assertEquals(8, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='ARCHIVE']");
+ assertEquals(1, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='BINARY']");
+ assertEquals(2, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='GENERATED']");
+ assertEquals(1, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='UNKNOWN']");
+ assertEquals(0, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='NOTICE']");
+ assertEquals(2, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource/sample");
+ assertEquals(1, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath, "/rat-report/resource[@type='GENERATED']/license/notes");
+ assertEquals(1, nodeList.getLength());
+
+ nodeList = XmlUtils.getNodeList(doc, xPath,
+ "/rat-report/resource[@name='target/test-classes/elements/Source.java']/sample");
+ assertEquals(1, nodeList.getLength());
+ }
/**
* Finds a node via xpath on the document. And then checks family, approval and
* type of elements of the node.
@@ -89,7 +213,8 @@
final ReportConfiguration configuration = new ReportConfiguration(DefaultLog.INSTANCE);
configuration.setStyleReport(false);
configuration.setFrom(defaults);
- configuration.setReportable(new DirectoryWalker(new File(elementsPath), configuration.getFilesToIgnore(), HiddenFileFilter.HIDDEN));
+ configuration.setDirectoriesToIgnore(HiddenFileFilter.HIDDEN);
+ configuration.setReportable(new DirectoryWalker(configuration, new FileDocument(new File(elementsPath))));
configuration.setOut(() -> out);
new Reporter(configuration).output();
Document doc = XmlUtils.toDom(new ByteArrayInputStream(out.toByteArray()));
@@ -151,7 +276,8 @@
final String elementsPath = Resources.getResourceDirectory("elements/Source.java");
final ReportConfiguration configuration = new ReportConfiguration(DefaultLog.INSTANCE);
configuration.setFrom(defaults);
- configuration.setReportable(new DirectoryWalker(new File(elementsPath), configuration.getFilesToIgnore(), HiddenFileFilter.HIDDEN));
+ configuration.setDirectoriesToIgnore(HiddenFileFilter.HIDDEN);
+ configuration.setReportable(new DirectoryWalker(configuration, new FileDocument(new File(elementsPath))));
configuration.setOut(() -> out);
new Reporter(configuration).output();
@@ -160,43 +286,43 @@
assertTrue(document.startsWith(HEADER), "'Generated at' is not present in " + document);
- TextUtils.assertPatternInOutput("^Notes: 2$", document);
- TextUtils.assertPatternInOutput("^Binaries: 2$", document);
- TextUtils.assertPatternInOutput("^Archives: 1$", document);
- TextUtils.assertPatternInOutput("^Standards: 8$", document);
- TextUtils.assertPatternInOutput("^Apache Licensed: 5$", document);
- TextUtils.assertPatternInOutput("^Generated Documents: 1$", document);
- TextUtils.assertPatternInOutput("^2 Unknown Licenses$", document);
- TextUtils.assertPatternInOutput(
+ TextUtils.assertPatternInTarget("^Notes: 2$", document);
+ TextUtils.assertPatternInTarget("^Binaries: 2$", document);
+ TextUtils.assertPatternInTarget("^Archives: 1$", document);
+ TextUtils.assertPatternInTarget("^Standards: 8$", document);
+ TextUtils.assertPatternInTarget("^Apache Licensed: 5$", document);
+ TextUtils.assertPatternInTarget("^Generated Documents: 1$", document);
+ TextUtils.assertPatternInTarget("^2 Unknown Licenses$", document);
+ TextUtils.assertPatternInTarget(
"^Files with unapproved licenses:\\s+" //
+ "\\Qsrc/test/resources/elements/Source.java\\E\\s+" //
+ "\\Qsrc/test/resources/elements/sub/Empty.txt\\E\\s",
document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.ARCHIVE, "src/test/resources/elements/dummy.jar"),
+ TextUtils.assertPatternInTarget(documentOut(true, Type.ARCHIVE, "src/test/resources/elements/dummy.jar"),
document);
- TextUtils.assertPatternInOutput(
+ TextUtils.assertPatternInTarget(
documentOut(true, Type.STANDARD, "src/test/resources/elements/ILoggerFactory.java")
+ licenseOut("MIT", "The MIT License"),
document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.BINARY, "src/test/resources/elements/Image.png"),
+ TextUtils.assertPatternInTarget(documentOut(true, Type.BINARY, "src/test/resources/elements/Image.png"),
document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.NOTICE, "src/test/resources/elements/LICENSE"),
+ TextUtils.assertPatternInTarget(documentOut(true, Type.NOTICE, "src/test/resources/elements/LICENSE"),
document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.NOTICE, "src/test/resources/elements/NOTICE"), document);
- TextUtils.assertPatternInOutput(documentOut(false, Type.STANDARD, "src/test/resources/elements/Source.java")
+ TextUtils.assertPatternInTarget(documentOut(true, Type.NOTICE, "src/test/resources/elements/NOTICE"), document);
+ TextUtils.assertPatternInTarget(documentOut(false, Type.STANDARD, "src/test/resources/elements/Source.java")
+ licenseOut("?????", "Unknown license (Unapproved)"), document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.STANDARD, "src/test/resources/elements/Text.txt")
+ TextUtils.assertPatternInTarget(documentOut(true, Type.STANDARD, "src/test/resources/elements/Text.txt")
+ licenseOut("AL", "Apache License Version 2.0"), document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.STANDARD, "src/test/resources/elements/Xml.xml")
+ TextUtils.assertPatternInTarget(documentOut(true, Type.STANDARD, "src/test/resources/elements/Xml.xml")
+ licenseOut("AL", "Apache License Version 2.0"), document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.STANDARD, "src/test/resources/elements/buildr.rb")
+ TextUtils.assertPatternInTarget(documentOut(true, Type.STANDARD, "src/test/resources/elements/buildr.rb")
+ licenseOut("AL", "Apache License Version 2.0"), document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.STANDARD, "src/test/resources/elements/TextHttps.txt")
+ TextUtils.assertPatternInTarget(documentOut(true, Type.STANDARD, "src/test/resources/elements/TextHttps.txt")
+ licenseOut("AL", "Apache License Version 2.0"), document);
- TextUtils.assertPatternInOutput(documentOut(true, Type.STANDARD, "src/test/resources/elements/tri.txt")
+ TextUtils.assertPatternInTarget(documentOut(true, Type.STANDARD, "src/test/resources/elements/tri.txt")
+ licenseOut("AL", "Apache License Version 2.0") + licenseOut("BSD-3", "BSD 3 clause")
+ licenseOut("BSD-3", "TMF", "The Telemanagement Forum License"), document);
- TextUtils.assertPatternInOutput(documentOut(false, Type.STANDARD, "src/test/resources/elements/sub/Empty.txt")
+ TextUtils.assertPatternInTarget(documentOut(false, Type.STANDARD, "src/test/resources/elements/sub/Empty.txt")
+ licenseOut("?????", "Unknown license (Unapproved)"), document);
}
@@ -208,7 +334,8 @@
final String elementsPath = Resources.getResourceDirectory("elements/Source.java");
final ReportConfiguration configuration = new ReportConfiguration(DefaultLog.INSTANCE);
configuration.setFrom(defaults);
- configuration.setReportable(new DirectoryWalker(new File(elementsPath), configuration.getFilesToIgnore(), HiddenFileFilter.HIDDEN));
+ configuration.setDirectoriesToIgnore(HiddenFileFilter.HIDDEN);
+ configuration.setReportable(new DirectoryWalker(configuration, new FileDocument(new File(elementsPath))));
configuration.setOut(() -> out);
configuration.setStyleSheet(this.getClass().getResource("/org/apache/rat/unapproved-licenses.xsl"));
new Reporter(configuration).output();
@@ -218,8 +345,8 @@
assertTrue(document.startsWith("Generated at: "), "'Generated at' is not present in " + document);
- TextUtils.assertPatternInOutput("\\Qsrc/test/resources/elements/Source.java\\E$", document);
- TextUtils.assertPatternInOutput("\\Qsrc/test/resources/elements/sub/Empty.txt\\E", document);
+ TextUtils.assertPatternInTarget("\\Qsrc/test/resources/elements/Source.java\\E$", document);
+ TextUtils.assertPatternInTarget("\\Qsrc/test/resources/elements/sub/Empty.txt\\E", document);
}
private static class LicenseInfo {
diff --git a/apache-rat-core/src/test/java/org/apache/rat/analysis/AnalyserFactoryTest.java b/apache-rat-core/src/test/java/org/apache/rat/analysis/AnalyserFactoryTest.java
deleted file mode 100644
index 9484b6f..0000000
--- a/apache-rat-core/src/test/java/org/apache/rat/analysis/AnalyserFactoryTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- */
-package org.apache.rat.analysis;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.io.StringWriter;
-import java.util.Arrays;
-
-import org.apache.rat.document.IDocumentAnalyser;
-import org.apache.rat.document.impl.MonolithicFileDocument;
-import org.apache.rat.license.ILicense;
-import org.apache.rat.report.claim.impl.xml.SimpleXmlClaimReporter;
-import org.apache.rat.report.xml.writer.impl.base.XmlWriter;
-import org.apache.rat.test.utils.Resources;
-import org.apache.rat.testhelpers.TextUtils;
-import org.apache.rat.utils.DefaultLog;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-public class AnalyserFactoryTest {
-
- private static ILicense MATCHES_NOTHING_MATCHER = UnknownLicense.INSTANCE;
-
- private StringWriter out;
- private SimpleXmlClaimReporter reporter;
- private IDocumentAnalyser analyser;
-
- @BeforeEach
- public void setUp() throws Exception {
- out = new StringWriter();
- reporter = new SimpleXmlClaimReporter(new XmlWriter(out));
- analyser = DefaultAnalyserFactory.createDefaultAnalyser(DefaultLog.INSTANCE,
- Arrays.asList(MATCHES_NOTHING_MATCHER));
- }
-
- @Test
- public void standardTypeAnalyser() throws Exception {
- String[] expected = {
- "<resource name='src/test/resources/elements/Text.txt' type='STANDARD'>"
- + "<license id='?????' name='Unknown license' approval='false' family='?????'/>"
- + "<sample><![CDATA[ /*", //
- " * Licensed to the Apache Software Foundation (ASF) under one", //
- " * or more contributor license agreements. See the NOTICE file", //
- " * distributed with this work for additional information", //
- " * regarding copyright ownership. The ASF licenses this file", //
- " * to you under the Apache License, Version 2.0 (the \"License\");", //
- " * you may not use this file except in compliance with the License.", //
- " * You may obtain a copy of the License at", //
- " * http://www.apache.org/licenses/LICENSE-2.0", //
- " * Unless required by applicable law or agreed to in writing,", //
- " * software distributed under the License is distributed on an", //
- " * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY", //
- " * KIND, either express or implied. See the License for the", //
- " * specific language governing permissions and limitations", //
- " * under the License.", //
- " ]]></sample></resource>" };
-
- final MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/elements/Text.txt"));
- analyser.analyse(document);
- reporter.report(document);
- String result = out.toString();
- for (String exp : expected) {
- assertTrue(result.contains(exp), () -> exp);
- }
- }
-
- @Test
- public void noteTypeAnalyser() throws Exception {
- final MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/elements/LICENSE"));
- analyser.analyse(document);
- reporter.report(document);
- assertEquals("<resource name='src/test/resources/elements/LICENSE' type='NOTICE'/>", out.toString(),
- "Open note element");
- }
-
- @Test
- public void binaryTypeAnalyser() throws Exception {
- final MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/elements/Image.png"));
- analyser.analyse(document);
- reporter.report(document);
- assertEquals("<resource name='src/test/resources/elements/Image.png' type='BINARY'/>", out.toString(),
- "Open binary element");
- }
-
- @Test
- public void archiveTypeAnalyser() throws Exception {
- final MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/elements/dummy.jar"));
- analyser.analyse(document);
- reporter.report(document);
- assertEquals("<resource name='src/test/resources/elements/dummy.jar' type='ARCHIVE'/>", out.toString(),
- "Open archive element");
- }
-
- @Test
- public void archiveTypeAnalyserIntelliJ() throws Exception {
- final MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/elements/dummy.jar"));
- analyser.analyse(document);
- reporter.report(document);
- assertEquals("<resource name='src/test/resources/elements/dummy.jar' type='ARCHIVE'/>", out.toString(),
- "Open archive element");
- }
-
- @Test
- public void RAT211_bmp_Test() throws Exception {
- MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/jira/RAT211/side_left.bmp"));
- analyser.analyse(document);
- reporter.report(document);
- assertEquals("<resource name='src/test/resources/jira/RAT211/side_left.bmp' type='BINARY'/>", out.toString(),
- "Open archive element");
- }
-
- @Test
- public void RAT211_dia_Test() throws Exception {
- MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/jira/RAT211/leader-election-message-arrives.dia"));
- analyser.analyse(document);
- reporter.report(document);
- assertEquals(
- "<resource name='src/test/resources/jira/RAT211/leader-election-message-arrives.dia' type='ARCHIVE'/>",
- out.toString(), "Open archive element");
- }
-
- @Test
- public void RAT147_unix_Test() throws Exception {
- MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/jira/RAT147/unix-newlines.txt.bin"));
- analyser.analyse(document);
- reporter.report(document);
- String result = out.toString();
- TextUtils.assertPatternInOutput(
- "<resource name='src/test/resources/jira/RAT147/unix-newlines.txt.bin' type='STANDARD'",
- result);
- TextUtils.assertPatternInOutput("sentence 1.$", result);
- TextUtils.assertPatternInOutput("^sentence 2.$", result);
- TextUtils.assertPatternInOutput("^sentence 3.$", result);
- TextUtils.assertPatternInOutput("^sentence 4.$", result);
- }
-
- @Test
- public void RAT147_windows_Test() throws Exception {
- MonolithicFileDocument document = new MonolithicFileDocument(
- Resources.getResourceFile("/jira/RAT147/windows-newlines.txt.bin"));
- analyser.analyse(document);
- reporter.report(document);
- String result = out.toString();
- TextUtils.assertPatternInOutput(
- "<resource name='src/test/resources/jira/RAT147/windows-newlines.txt.bin' type='STANDARD'",
- result);
- TextUtils.assertPatternInOutput("sentence 1.$", result);
- TextUtils.assertPatternInOutput("^sentence 2.$", result);
- TextUtils.assertPatternInOutput("^sentence 3.$", result);
- TextUtils.assertPatternInOutput("^sentence 4.$", result);
- }
-}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/analysis/DefaultAnalyserFactoryTest.java b/apache-rat-core/src/test/java/org/apache/rat/analysis/DefaultAnalyserFactoryTest.java
new file mode 100644
index 0000000..3070b31
--- /dev/null
+++ b/apache-rat-core/src/test/java/org/apache/rat/analysis/DefaultAnalyserFactoryTest.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ */
+package org.apache.rat.analysis;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.StringWriter;
+
+import org.apache.commons.io.filefilter.FalseFileFilter;
+import org.apache.rat.Defaults;
+import org.apache.rat.ReportConfiguration;
+import org.apache.rat.api.Document;
+import org.apache.rat.document.IDocumentAnalyser;
+import org.apache.rat.document.impl.FileDocument;
+import org.apache.rat.report.claim.impl.xml.SimpleXmlClaimReporter;
+import org.apache.rat.report.xml.writer.impl.base.XmlWriter;
+import org.apache.rat.test.utils.Resources;
+import org.apache.rat.testhelpers.TextUtils;
+import org.apache.rat.utils.DefaultLog;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class DefaultAnalyserFactoryTest {
+
+ private StringWriter out;
+ private SimpleXmlClaimReporter reporter;
+ private IDocumentAnalyser analyser;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ out = new StringWriter();
+ reporter = new SimpleXmlClaimReporter(new XmlWriter(out));
+ ReportConfiguration config = new ReportConfiguration(DefaultLog.INSTANCE);
+ config.addLicense(UnknownLicense.INSTANCE);
+ analyser = DefaultAnalyserFactory.createDefaultAnalyser(config);
+ }
+
+ @Test
+ public void standardTypeAnalyser() throws Exception {
+ String[] expected = {
+ "<resource name='src/test/resources/elements/Text.txt' type='STANDARD'>"
+ + "<license id='?????' name='Unknown license' approval='false' family='?????'/>"
+ + "<sample><![CDATA[ /*", //
+ " * Licensed to the Apache Software Foundation (ASF) under one", //
+ " * or more contributor license agreements. See the NOTICE file", //
+ " * distributed with this work for additional information", //
+ " * regarding copyright ownership. The ASF licenses this file", //
+ " * to you under the Apache License, Version 2.0 (the \"License\");", //
+ " * you may not use this file except in compliance with the License.", //
+ " * You may obtain a copy of the License at", //
+ " * http://www.apache.org/licenses/LICENSE-2.0", //
+ " * Unless required by applicable law or agreed to in writing,", //
+ " * software distributed under the License is distributed on an", //
+ " * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY", //
+ " * KIND, either express or implied. See the License for the", //
+ " * specific language governing permissions and limitations", //
+ " * under the License.", //
+ " ]]></sample></resource>" };
+
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/elements/Text.txt"));
+ analyser.analyse(document);
+ reporter.report(document);
+ String result = out.toString();
+ for (String exp : expected) {
+ assertTrue(result.contains(exp), () -> exp);
+ }
+ }
+
+ @Test
+ public void noteTypeAnalyser() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/elements/LICENSE"));
+ analyser.analyse(document);
+ reporter.report(document);
+ assertEquals("<resource name='src/test/resources/elements/LICENSE' type='NOTICE'/>", out.toString());
+ }
+
+ @Test
+ public void binaryTypeAnalyser() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/elements/Image.png"));
+ analyser.analyse(document);
+ reporter.report(document);
+ assertEquals("<resource name='src/test/resources/elements/Image.png' type='BINARY'/>", out.toString());
+ }
+
+ @Test
+ public void archiveTypeAnalyserTest() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/elements/dummy.jar"));
+ Defaults defaults = Defaults.builder().build(DefaultLog.INSTANCE);
+ ReportConfiguration config = new ReportConfiguration(DefaultLog.INSTANCE);
+ config.setFrom(defaults);
+ config.setFilesToIgnore(FalseFileFilter.FALSE);
+ analyser = DefaultAnalyserFactory.createDefaultAnalyser(config);
+ analyser.analyse(document);
+ reporter.report(document);
+ assertEquals("<resource name='src/test/resources/elements/dummy.jar' type='ARCHIVE'/>", out.toString());
+ }
+
+ @Test
+ public void archivesAbsenceTest() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/elements/dummy.jar"));
+ Defaults defaults = Defaults.builder().build(DefaultLog.INSTANCE);
+ ReportConfiguration config = new ReportConfiguration(DefaultLog.INSTANCE);
+ config.setFrom(defaults);
+ config.setFilesToIgnore(FalseFileFilter.FALSE);
+ config.setArchiveProcessing(ReportConfiguration.Processing.ABSENCE);
+ analyser = DefaultAnalyserFactory.createDefaultAnalyser(config);
+ analyser.analyse(document);
+ reporter.report(document);
+ String result = out.toString();
+ TextUtils.assertContains("<resource name='src/test/resources/elements/dummy.jar' type='ARCHIVE'>", out.toString());
+ TextUtils.assertContains("<license id='?????' name='Unknown license' approval='false' family='?????'/>", out.toString());
+ TextUtils.assertContains("<license id='ASL' name='Applied Apache License Version 2.0' approval='false' family='AL '/>", out.toString());
+ }
+
+ @Test
+ public void archivesPresenceTest() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/elements/dummy.jar"));
+ Defaults defaults = Defaults.builder().build(DefaultLog.INSTANCE);
+ ReportConfiguration config = new ReportConfiguration(DefaultLog.INSTANCE);
+ config.setFrom(defaults);
+ config.setFilesToIgnore(FalseFileFilter.FALSE);
+ config.setArchiveProcessing(ReportConfiguration.Processing.PRESENCE);
+ analyser = DefaultAnalyserFactory.createDefaultAnalyser(config);
+ analyser.analyse(document);
+ reporter.report(document);
+ String result = out.toString();
+ TextUtils.assertContains("<resource name='src/test/resources/elements/dummy.jar' type='ARCHIVE'>", out.toString());
+ TextUtils.assertNotContains("<license id='?????' name='Unknown license' approval='false' family='?????'/>", out.toString());
+ TextUtils.assertContains("<license id='ASL' name='Applied Apache License Version 2.0' approval='false' family='AL '/>", out.toString());
+ }
+
+ @Test
+ public void archiveTypeAnalyserIntelliJ() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/elements/dummy.jar"));
+ analyser.analyse(document);
+ reporter.report(document);
+ assertEquals("<resource name='src/test/resources/elements/dummy.jar' type='ARCHIVE'/>", out.toString());
+ }
+
+ @Test
+ public void RAT211_bmp_Test() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/jira/RAT211/side_left.bmp"));
+ analyser.analyse(document);
+ reporter.report(document);
+ assertEquals("<resource name='src/test/resources/jira/RAT211/side_left.bmp' type='BINARY'/>", out.toString());
+ }
+
+ @Test
+ public void RAT211_dia_Test() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/jira/RAT211/leader-election-message-arrives.dia"));
+ analyser.analyse(document);
+ reporter.report(document);
+ assertEquals(
+ "<resource name='src/test/resources/jira/RAT211/leader-election-message-arrives.dia' type='ARCHIVE'/>",
+ out.toString());
+ }
+
+ @Test
+ public void RAT147_unix_Test() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/jira/RAT147/unix-newlines.txt.bin"));
+ analyser.analyse(document);
+ reporter.report(document);
+ String result = out.toString();
+ TextUtils.assertPatternInTarget(
+ "<resource name='src/test/resources/jira/RAT147/unix-newlines.txt.bin' type='STANDARD'",
+ result);
+ TextUtils.assertPatternInTarget("sentence 1.$", result);
+ TextUtils.assertPatternInTarget("^sentence 2.$", result);
+ TextUtils.assertPatternInTarget("^sentence 3.$", result);
+ TextUtils.assertPatternInTarget("^sentence 4.$", result);
+ }
+
+ @Test
+ public void RAT147_windows_Test() throws Exception {
+ final Document document = new FileDocument(
+ Resources.getResourceFile("/jira/RAT147/windows-newlines.txt.bin"));
+ analyser.analyse(document);
+ reporter.report(document);
+ String result = out.toString();
+ TextUtils.assertPatternInTarget(
+ "<resource name='src/test/resources/jira/RAT147/windows-newlines.txt.bin' type='STANDARD'",
+ result);
+ TextUtils.assertPatternInTarget("sentence 1.$", result);
+ TextUtils.assertPatternInTarget("^sentence 2.$", result);
+ TextUtils.assertPatternInTarget("^sentence 3.$", result);
+ TextUtils.assertPatternInTarget("^sentence 4.$", result);
+ }
+}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/analysis/HeaderCheckWorkerTest.java b/apache-rat-core/src/test/java/org/apache/rat/analysis/HeaderCheckWorkerTest.java
index 8dcfdf3..36e5cdc 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/analysis/HeaderCheckWorkerTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/analysis/HeaderCheckWorkerTest.java
@@ -23,9 +23,9 @@
import java.util.Arrays;
import org.apache.rat.api.Document;
+import org.apache.rat.testhelpers.TestingDocument;
import org.apache.rat.license.ILicense;
import org.apache.rat.testhelpers.TestingLicense;
-import org.apache.rat.testhelpers.TestingLocation;
import org.junit.jupiter.api.Test;
@@ -33,7 +33,7 @@
@Test
public void isFinished() throws Exception {
- final Document subject = new TestingLocation("subject");
+ final Document subject = new TestingDocument("subject");
ILicense matcher = new TestingLicense();
HeaderCheckWorker worker = new HeaderCheckWorker(new StringReader(""), Arrays.asList(matcher), subject);
worker.read();
diff --git a/apache-rat-core/src/test/java/org/apache/rat/analysis/TikaProcessorTest.java b/apache-rat-core/src/test/java/org/apache/rat/analysis/TikaProcessorTest.java
index aef464d..ad76070 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/analysis/TikaProcessorTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/analysis/TikaProcessorTest.java
@@ -34,9 +34,7 @@
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.MalformedInputException;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -135,13 +133,8 @@
* @return
*/
private static Document getDocument(final InputStream stream) {
- MetaData metaData = new MetaData();
- Document doc = new Document() {
- @Override
- public String getName() {
- return "Testing Document";
- }
+ Document doc = new Document("Testing Document") {
@Override
public Reader reader() throws IOException {
@@ -154,13 +147,13 @@
}
@Override
- public MetaData getMetaData() {
- return metaData;
+ public boolean isDirectory() {
+ return false;
}
@Override
- public boolean isComposite() {
- return false;
+ public SortedSet<Document> listChildren() {
+ return Collections.emptySortedSet();
}
};
return doc;
diff --git a/apache-rat-core/src/test/java/org/apache/rat/document/impl/SingularFileDocumentTest.java b/apache-rat-core/src/test/java/org/apache/rat/document/impl/FileDocumentTest.java
similarity index 92%
rename from apache-rat-core/src/test/java/org/apache/rat/document/impl/SingularFileDocumentTest.java
rename to apache-rat-core/src/test/java/org/apache/rat/document/impl/FileDocumentTest.java
index b074e01..bfeba21 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/document/impl/SingularFileDocumentTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/document/impl/FileDocumentTest.java
@@ -30,14 +30,14 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-public class SingularFileDocumentTest {
+public class FileDocumentTest {
private Document document;
private File file;
@BeforeEach
public void setUp() throws Exception {
file = Resources.getResourceFile("elements/Source.java");
- document = new MonolithicFileDocument(file);
+ document = new FileDocument(file);
}
@Test
@@ -52,6 +52,6 @@
public void getName() {
final String name = document.getName();
assertNotNull("Name is set", name);
- assertEquals(DocumentImplUtils.toName(file), name, "Name is filename");
+ assertEquals(FileDocument.normalizeFileName(file), name, "Name is filename");
}
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/document/impl/guesser/NoteGuesserTest.java b/apache-rat-core/src/test/java/org/apache/rat/document/impl/guesser/NoteGuesserTest.java
index 82ca98c..2987adf 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/document/impl/guesser/NoteGuesserTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/document/impl/guesser/NoteGuesserTest.java
@@ -18,7 +18,7 @@
*/
package org.apache.rat.document.impl.guesser;
-import org.apache.rat.document.MockDocument;
+import org.apache.rat.testhelpers.TestingDocument;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -27,13 +27,13 @@
@Test
public void testMatches() {
- assertTrue(NoteGuesser.isNote(new MockDocument("DEPENDENCIES")));
- assertTrue(NoteGuesser.isNote(new MockDocument("LICENSE")));
- assertTrue(NoteGuesser.isNote(new MockDocument("LICENSE.txt")));
- assertTrue(NoteGuesser.isNote(new MockDocument("NOTICE")));
- assertTrue(NoteGuesser.isNote(new MockDocument("NOTICE.txt")));
- assertTrue(NoteGuesser.isNote(new MockDocument("README")));
- assertTrue(NoteGuesser.isNote(new MockDocument("README.txt")));
+ assertTrue(NoteGuesser.isNote(new TestingDocument("DEPENDENCIES")));
+ assertTrue(NoteGuesser.isNote(new TestingDocument("LICENSE")));
+ assertTrue(NoteGuesser.isNote(new TestingDocument("LICENSE.txt")));
+ assertTrue(NoteGuesser.isNote(new TestingDocument("NOTICE")));
+ assertTrue(NoteGuesser.isNote(new TestingDocument("NOTICE.txt")));
+ assertTrue(NoteGuesser.isNote(new TestingDocument("README")));
+ assertTrue(NoteGuesser.isNote(new TestingDocument("README.txt")));
}
@Test
diff --git a/apache-rat-core/src/test/java/org/apache/rat/document/impl/util/DocumentAnalyserMultiplexerTest.java b/apache-rat-core/src/test/java/org/apache/rat/document/impl/util/DocumentAnalyserMultiplexerTest.java
index 1d4f9c6..743b439 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/document/impl/util/DocumentAnalyserMultiplexerTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/document/impl/util/DocumentAnalyserMultiplexerTest.java
@@ -19,8 +19,8 @@
package org.apache.rat.document.impl.util;
import org.apache.rat.document.IDocumentAnalyser;
-import org.apache.rat.document.MockDocument;
-import org.apache.rat.document.MockDocumentAnalyser;
+import org.apache.rat.testhelpers.TestingDocument;
+import org.apache.rat.testhelpers.TestingDocumentAnalyser;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -30,30 +30,30 @@
private DocumentAnalyserMultiplexer multiplexer;
private IDocumentAnalyser[] analysers;
- private MockDocument document;
+ private TestingDocument document;
@BeforeEach
public void setUp() {
IDocumentAnalyser[] analysers = {
- new MockDocumentAnalyser(),
- new MockDocumentAnalyser(),
- new MockDocumentAnalyser()
+ new TestingDocumentAnalyser(),
+ new TestingDocumentAnalyser(),
+ new TestingDocumentAnalyser()
};
this.analysers = analysers;
- document = new MockDocument();
+ document = new TestingDocument();
multiplexer = new DocumentAnalyserMultiplexer(analysers);
}
@Test
public void testAnalyse() throws Exception {
multiplexer.analyse(document);
- MockDocumentAnalyser analyser = (MockDocumentAnalyser) (analysers[0]);
+ TestingDocumentAnalyser analyser = (TestingDocumentAnalyser) (analysers[0]);
assertEquals(1, analyser.matches.size(),"Call made to analyser");
assertEquals( document, analyser.matches.get(0), "Call made to analyser");
- analyser = (MockDocumentAnalyser) (analysers[1]);
+ analyser = (TestingDocumentAnalyser) (analysers[1]);
assertEquals(1, analyser.matches.size(), "Call made to analyser");
assertEquals(document, analyser.matches.get(0), "Call made to analyser");
- analyser = (MockDocumentAnalyser) (analysers[2]);
+ analyser = (TestingDocumentAnalyser) (analysers[2]);
assertEquals( 1, analyser.matches.size());
assertEquals( document, analyser.matches.get(0),"Call made to analyser");
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/policy/DefaultPolicyTest.java b/apache-rat-core/src/test/java/org/apache/rat/policy/DefaultPolicyTest.java
index cde06b7..250bf51 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/policy/DefaultPolicyTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/policy/DefaultPolicyTest.java
@@ -30,7 +30,7 @@
import org.apache.rat.license.LicenseFamilySetFactory;
import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
import org.apache.rat.testhelpers.TestingLicense;
-import org.apache.rat.testhelpers.TestingLocation;
+import org.apache.rat.testhelpers.TestingDocument;
import org.apache.rat.utils.DefaultLog;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -62,7 +62,7 @@
public void setUp() throws Exception {
defaults = Defaults.builder().build(DefaultLog.INSTANCE);
policy = new DefaultPolicy(defaults.getLicenseFamilies(LicenseFilter.APPROVED));
- document = new TestingLocation("subject");
+ document = new TestingDocument("subject");
}
private void assertApproval(boolean pApproved) {
@@ -153,7 +153,7 @@
Document.Type[] nonStandardDocuments = { Document.Type.NOTICE, Document.Type.ARCHIVE, Document.Type.BINARY };
for (Document.Type d : nonStandardDocuments) {
- document = new TestingLocation("subject");
+ document = new TestingDocument("subject");
document.getMetaData().setDocumentType(d);
policy.analyse(document);
assertEquals(0, document.getMetaData().licenses().count(), "failed on " + d);
diff --git a/apache-rat-core/src/test/java/org/apache/rat/report/xml/XmlReportFactoryTest.java b/apache-rat-core/src/test/java/org/apache/rat/report/xml/XmlReportFactoryTest.java
index e386f93..2860499 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/report/xml/XmlReportFactoryTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/report/xml/XmlReportFactoryTest.java
@@ -34,6 +34,7 @@
import org.apache.rat.Defaults;
import org.apache.rat.ReportConfiguration;
import org.apache.rat.api.Document;
+import org.apache.rat.document.impl.FileDocument;
import org.apache.rat.license.ILicense;
import org.apache.rat.license.ILicenseFamily;
import org.apache.rat.report.RatReport;
@@ -74,8 +75,8 @@
final ReportConfiguration configuration = new ReportConfiguration(DefaultLog.INSTANCE);
final TestingLicense testingLicense = new TestingLicense(new TestingMatcher(true), family);
configuration.setFrom(Defaults.builder().build(DefaultLog.INSTANCE));
-
- DirectoryWalker directory = new DirectoryWalker(new File(elementsPath), configuration.getFilesToIgnore(), HiddenFileFilter.HIDDEN);
+ configuration.setDirectoriesToIgnore(HiddenFileFilter.HIDDEN);
+ DirectoryWalker directory = new DirectoryWalker(configuration, new FileDocument(new File(elementsPath)));
final ClaimStatistic statistic = new ClaimStatistic();
configuration.addLicense(testingLicense);
diff --git a/apache-rat-core/src/test/java/org/apache/rat/test/utils/Resources.java b/apache-rat-core/src/test/java/org/apache/rat/test/utils/Resources.java
index 8ebcca1..6229393 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/test/utils/Resources.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/test/utils/Resources.java
@@ -29,7 +29,7 @@
import java.io.Reader;
import java.nio.charset.StandardCharsets;
-import org.apache.rat.document.impl.DocumentImplUtils;
+import org.apache.rat.document.impl.FileDocument;
/**
* Utility class, which provides static methods for creating test cases.
@@ -127,6 +127,6 @@
public static String getResourceDirectory(String pResource) throws IOException {
final File resource = getResourceFile(pResource);
final File dir = resource.getParentFile();
- return DocumentImplUtils.toName(dir);
+ return FileDocument.normalizeFileName(dir);
}
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/document/MockDocument.java b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
similarity index 74%
rename from apache-rat-core/src/test/java/org/apache/rat/document/MockDocument.java
rename to apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
index 743aa25..3b77f3e 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/document/MockDocument.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
@@ -16,33 +16,32 @@
* specific language governing permissions and limitations *
* under the License. *
*/
-package org.apache.rat.document;
+package org.apache.rat.testhelpers;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.util.Collections;
+import java.util.SortedSet;
import org.apache.rat.api.Document;
-import org.apache.rat.api.MetaData;
-public class MockDocument implements Document {
+public class TestingDocument extends Document {
private final Reader reader;
- private final String name;
- private final MetaData metaData = new MetaData();
- public MockDocument() {
+ public TestingDocument() {
this(null, "name");
}
- public MockDocument(String name) {
+ public TestingDocument(String name) {
this(null, name);
}
- public MockDocument(Reader reader, String name) {
- super();
+ public TestingDocument(Reader reader, String name) {
+ super(name);
this.reader = reader;
- this.name = name;
+
}
@Override
@@ -51,20 +50,16 @@
}
@Override
- public String getName() {
- return name;
- }
-
- @Override
- public boolean isComposite() {
+ public boolean isDirectory() {
return false;
}
@Override
- public MetaData getMetaData() {
- return metaData;
+ public SortedSet<Document> listChildren() {
+ return Collections.emptySortedSet();
}
+
@Override
public InputStream inputStream() throws IOException {
throw new UnsupportedOperationException();
diff --git a/apache-rat-core/src/test/java/org/apache/rat/document/MockDocumentAnalyser.java b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocumentAnalyser.java
similarity index 86%
rename from apache-rat-core/src/test/java/org/apache/rat/document/MockDocumentAnalyser.java
rename to apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocumentAnalyser.java
index c5b513e..f8c78d4 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/document/MockDocumentAnalyser.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocumentAnalyser.java
@@ -16,19 +16,20 @@
* specific language governing permissions and limitations *
* under the License. *
*/
-package org.apache.rat.document;
+package org.apache.rat.testhelpers;
import java.util.ArrayList;
import java.util.List;
import org.apache.rat.api.Document;
+import org.apache.rat.document.IDocumentAnalyser;
-public class MockDocumentAnalyser implements IDocumentAnalyser {
+public class TestingDocumentAnalyser implements IDocumentAnalyser {
public final List<Document> matches = new ArrayList<>();
@Override
- public void analyse(Document document) throws RatDocumentAnalysisException {
+ public void analyse(Document document) {
matches.add(document);
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingLocation.java b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingLocation.java
deleted file mode 100644
index 0425da8..0000000
--- a/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingLocation.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- */
-package org.apache.rat.testhelpers;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-import org.apache.rat.api.Document;
-import org.apache.rat.api.MetaData;
-
-public class TestingLocation implements Document {
-
- public final String name;
- public final String url;
- private final MetaData metaData = new MetaData();
-
- public TestingLocation() {
- this("name", "url");
- }
-
- public TestingLocation(String name) {
- this(name, "url");
- }
-
- public TestingLocation(String name, String url) {
- super();
- this.name = name;
- this.url = url;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- public String getURL() {
- return url;
- }
-
- @Override
- public boolean isComposite() {
- return false;
- }
-
- @Override
- public Reader reader() throws IOException {
- throw new UnsupportedOperationException("Opening Reader in TestingLocation");
- }
-
- @Override
- public MetaData getMetaData() {
- return metaData;
- }
-
- @Override
- public InputStream inputStream() throws IOException {
- throw new UnsupportedOperationException("Opening inputStream in TestingLocation");
- }
-}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TextUtils.java b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TextUtils.java
index 41bb196..a88f70f 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TextUtils.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TextUtils.java
@@ -26,23 +26,56 @@
public class TextUtils {
public static final String[] EMPTY = {};
-
- public static void assertPatternInOutput(String pattern, String out) {
+
+ /**
+ * Asserts a regular expression pattern is in a string
+ *
+ * @param pattern the pattern to match.
+ * @param target the string to match.
+ */
+ public static void assertPatternInTarget(String pattern, String target) {
assertTrue(
- isMatching(pattern, out), ()->"Output does not match string: " + pattern+"\n"+out);
- }
-
- public static void assertPatternNotInOutput(String pattern, String out) {
- assertFalse(
- isMatching(pattern, out), ()->"Output matches the pattern: " + pattern+"\n"+out);
+ isMatching(pattern, target), () -> "Target does not match string: " + pattern + "\n" + target);
}
- public static boolean isMatching(final String pattern, final String value) {
- return Pattern.compile(pattern, Pattern.MULTILINE).matcher(value).find();
+ /**
+ * Asserts a regular expression pattern is not in a string
+ *
+ * @param pattern the pattern to match.
+ * @param target the string to match.
+ */
+ public static void assertPatternNotInTarget(String pattern, String target) {
+ assertFalse(
+ isMatching(pattern, target), () -> "Target matches the pattern: " + pattern + "\n" + target);
}
-
- public static void find(String pattern, String document) {
- assertTrue(
- Pattern.compile(pattern, Pattern.MULTILINE).matcher(document).find(), () ->String.format("Could not find '%s'", pattern));
- }
+
+ /**
+ * Returns {@code true} if a regular expression pattern is in a string
+ *
+ * @param pattern the pattern to match.
+ * @param target the string to match.
+ */
+ public static boolean isMatching(final String pattern, final String target) {
+ return Pattern.compile(pattern, Pattern.MULTILINE).matcher(target).find();
+ }
+
+ /**
+ * Asserts that a string is contained within another string.
+ * @param find The string to find.
+ * @param target The string to search.
+ */
+ public static void assertContains(final String find, final String target) {
+ assertTrue(
+ target.contains(find), () -> "Target does not contain the text: " + find + "\n" + target);
+ }
+
+ /**
+ * Asserts that a string is not contained within another string.
+ * @param find The string to find.
+ * @param target The string to search.
+ */
+ public static void assertNotContains(final String find, final String target) {
+ assertFalse(
+ target.contains(find), () -> "Target does contain the text: " + find + "\n" + target);
+ }
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/walker/DirectoryWalkerTest.java b/apache-rat-core/src/test/java/org/apache/rat/walker/DirectoryWalkerTest.java
index 0fe276a..5c946e7 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/walker/DirectoryWalkerTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/walker/DirectoryWalkerTest.java
@@ -27,17 +27,23 @@
import java.util.ArrayList;
import java.util.List;
+import org.apache.commons.io.filefilter.FalseFileFilter;
+import org.apache.rat.ReportConfiguration;
import org.apache.rat.api.Document;
import org.apache.rat.api.RatException;
-import org.apache.rat.document.impl.DocumentImplUtils;
+import org.apache.rat.document.impl.FileDocument;
import org.apache.rat.report.RatReport;
+import org.apache.rat.utils.DefaultLog;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
public class DirectoryWalkerTest {
- private static File toWalk;
+ private static Document toWalk;
+ private ReportConfiguration reportConfiguration ;
+
private static void fileWriter(File dir, String name, String contents) throws IOException {
try (FileWriter writer = new FileWriter(new File(dir, name))) {
@@ -45,9 +51,15 @@
writer.flush();
}
}
+
+ @BeforeEach
+ public void beforeEach() {
+ reportConfiguration = new ReportConfiguration(DefaultLog.INSTANCE);
+ }
+
@BeforeAll
public static void setUp(@TempDir File dir) throws Exception {
- toWalk = dir;
+ toWalk = new FileDocument(dir);
/*
Create a directory structure like this:
@@ -58,26 +70,28 @@
regularFile
.hiddenFile
*/
- File regular = new File(toWalk, "regular");
+ File regular = new File(dir, "regular");
regular.mkdir();
fileWriter(regular, "regularFile", "regular file");
fileWriter(regular, ".hiddenFile", "hidden file");
- File hidden = new File(toWalk, ".hidden");
+ File hidden = new File(dir, ".hidden");
hidden.mkdir();
fileWriter(hidden, "regularFile", "regular file");
fileWriter(hidden, ".hiddenFile", "hidden file");
}
private String expectedName(String name) {
- return DocumentImplUtils.toName(toWalk)+name;
+ return toWalk.getName()+name;
}
@Test
public void noFiltersTest() throws IOException, RatException {
- DirectoryWalker walker = new DirectoryWalker(toWalk, null,null);
+ reportConfiguration.setFilesToIgnore(FalseFileFilter.FALSE);
+ reportConfiguration.setDirectoriesToIgnore(FalseFileFilter.FALSE);
+ DirectoryWalker walker = new DirectoryWalker(reportConfiguration, toWalk);
List<String> scanned = new ArrayList<>();
walker.run(new TestRatReport(scanned));
String[] expected = {"/regular/regularFile", "/regular/.hiddenFile", "/.hidden/regularFile", "/.hidden/.hiddenFile"};
@@ -89,7 +103,9 @@
@Test
public void noHiddenFileFiltersTest() throws IOException, RatException {
- DirectoryWalker walker = new DirectoryWalker(toWalk, NameBasedHiddenFileFilter.HIDDEN,null);
+ reportConfiguration.setFilesToIgnore(NameBasedHiddenFileFilter.HIDDEN);
+ reportConfiguration.setDirectoriesToIgnore(FalseFileFilter.FALSE);
+ DirectoryWalker walker = new DirectoryWalker(reportConfiguration, toWalk);
List<String> scanned = new ArrayList<>();
walker.run(new TestRatReport(scanned));
String[] expected = {"/regular/regularFile", "/.hidden/regularFile"};
@@ -101,7 +117,9 @@
@Test
public void noHiddenDirectoryFiltersTest() throws IOException, RatException {
- DirectoryWalker walker = new DirectoryWalker(toWalk, null, NameBasedHiddenFileFilter.HIDDEN);
+ reportConfiguration.setFilesToIgnore(FalseFileFilter.FALSE);
+ reportConfiguration.setDirectoriesToIgnore(NameBasedHiddenFileFilter.HIDDEN);
+ DirectoryWalker walker = new DirectoryWalker(reportConfiguration, toWalk);
List<String> scanned = new ArrayList<>();
walker.run(new TestRatReport(scanned));
String[] expected = {"/regular/regularFile", "/regular/.hiddenFile"};
@@ -113,7 +131,9 @@
@Test
public void noHiddenDirectoryAndNoHiddenFileFiltersTest() throws IOException, RatException {
- DirectoryWalker walker = new DirectoryWalker(toWalk, NameBasedHiddenFileFilter.HIDDEN, NameBasedHiddenFileFilter.HIDDEN);
+ reportConfiguration.setDirectoriesToIgnore(NameBasedHiddenFileFilter.HIDDEN);
+ reportConfiguration.setFilesToIgnore(NameBasedHiddenFileFilter.HIDDEN);
+ DirectoryWalker walker = new DirectoryWalker(reportConfiguration, toWalk);
List<String> scanned = new ArrayList<>();
walker.run(new TestRatReport(scanned));
String[] expected = {"/regular/regularFile"};
diff --git a/apache-rat-core/src/test/java/org/apache/rat/walker/FileNameComparatorTest.java b/apache-rat-core/src/test/java/org/apache/rat/walker/FileNameComparatorTest.java
deleted file mode 100644
index dd1e934..0000000
--- a/apache-rat-core/src/test/java/org/apache/rat/walker/FileNameComparatorTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you under the Apache License, Version 2.0 (the *
- * "License"); you may not use this file except in compliance *
- * with the License. You may obtain a copy of the License at *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, *
- * software distributed under the License is distributed on an *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
- * KIND, either express or implied. See the License for the *
- * specific language governing permissions and limitations *
- * under the License. *
- */
-package org.apache.rat.walker;
-
-import org.apache.rat.test.utils.Resources;
-import org.junit.jupiter.api.Test;
-
-import java.io.IOException;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class FileNameComparatorTest {
-
- @Test
- public void compare() throws IOException {
- FileNameComparator comparator = new FileNameComparator();
- assertNotNull(comparator);
- final int compare = comparator.compare(Resources.getResourceFile("elements/LICENSE"), Resources.getResourceFile("elements/NOTICE"));
- assertTrue(compare < 0, "LICENSE is before NOTICE");
- }
-}
diff --git a/apache-rat-plugin/src/main/java/org/apache/rat/mp/AbstractRatMojo.java b/apache-rat-plugin/src/main/java/org/apache/rat/mp/AbstractRatMojo.java
index 2386ed3..bf48681 100644
--- a/apache-rat-plugin/src/main/java/org/apache/rat/mp/AbstractRatMojo.java
+++ b/apache-rat-plugin/src/main/java/org/apache/rat/mp/AbstractRatMojo.java
@@ -346,8 +346,6 @@
config.setFrom(defaults);
} else {
config.setStyleSheet(Defaults.getPlainStyleSheet());
- config.setDirectoriesToIgnore(Defaults.getDirectoriesToIgnore());
- config.setFilesToIgnore(Defaults.getFilesToIgnore());
}
if (additionalLicenseFiles != null) {
diff --git a/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatTestHelpers.java b/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatTestHelpers.java
index f005474..bb4dfc2 100644
--- a/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatTestHelpers.java
+++ b/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatTestHelpers.java
@@ -206,11 +206,11 @@
List<String> lines = IOUtils.readLines(new FileInputStream(pRatTxtFile), Charsets.UTF_8);
String document = String.join("\n", lines);
for (String pattern : in) {
- TextUtils.assertPatternInOutput(pattern, document);
+ TextUtils.assertPatternInTarget(pattern, document);
}
for (String pattern : notIn) {
- TextUtils.assertPatternInOutput(pattern, document);
+ TextUtils.assertPatternInTarget(pattern, document);
}
}
diff --git a/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/ResourceCollectionContainer.java b/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/ResourceCollectionContainer.java
index ca474b9..2b2ddcd 100644
--- a/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/ResourceCollectionContainer.java
+++ b/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/ResourceCollectionContainer.java
@@ -24,11 +24,12 @@
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.SortedSet;
import org.apache.rat.api.Document;
-import org.apache.rat.api.MetaData;
import org.apache.rat.api.RatException;
-import org.apache.rat.document.impl.DocumentImplUtils;
+import org.apache.rat.document.impl.FileDocument;
import org.apache.rat.report.IReportable;
import org.apache.rat.report.RatReport;
import org.apache.tools.ant.types.Resource;
@@ -57,14 +58,20 @@
}
}
- private static class ResourceDocument implements Document {
+ private static class ResourceDocument extends Document {
private final Resource resource;
- private final MetaData metaData;
+
+ private static String asName(Resource resource) {
+ return resource instanceof FileResource ?
+ FileDocument.normalizeFileName(((FileResource) resource).getFile())
+ : resource.getName();
+ }
+
private ResourceDocument(Resource resource) {
+ super(asName(resource));
this.resource = resource;
- this.metaData = new MetaData();
}
@Override
@@ -74,32 +81,22 @@
}
@Override
- public String getName() {
- // TODO: reconsider names
- String result = null;
+ public boolean isDirectory() {
if (resource instanceof FileResource) {
final FileResource fileResource = (FileResource) resource;
final File file = fileResource.getFile();
- result = DocumentImplUtils.toName(file);
- } else {
- result = resource.getName();
- }
- return result;
- }
-
- @Override
- public boolean isComposite() {
- if (resource instanceof FileResource) {
- final FileResource fileResource = (FileResource) resource;
- final File file = fileResource.getFile();
- return DocumentImplUtils.isZip(file);
+ return file.isDirectory();
}
return false;
}
@Override
- public MetaData getMetaData() {
- return metaData;
+ public SortedSet<Document> listChildren() {
+ if (resource instanceof FileResource) {
+ final FileResource fileResource = (FileResource) resource;
+ return new FileDocument(fileResource.getFile()).listChildren();
+ }
+ return Collections.emptySortedSet();
}
@Override
diff --git a/apache-rat/src/site/apt/index.apt.vm b/apache-rat/src/site/apt/index.apt.vm
index 06baa08..93c2414 100644
--- a/apache-rat/src/site/apt/index.apt.vm
+++ b/apache-rat/src/site/apt/index.apt.vm
@@ -78,56 +78,72 @@
usage: java -jar apache-rat/target/apache-rat-${project.version}.jar
[options] [DIR|TARBALL]
-Available options
- -a (deprecated) Add the default license
- header to any file with an unknown
- license. Use '-A' or ---addLicense
- instead.
- -A,--addLicense Add the default license header to any file
- with an unknown license that is not in the
- exclusion list. By default new files will
- be created with the license header, to
- force the modification of existing files
- use the --force option.
- -c,--copyright <arg> The copyright message to use in the
- license headers, usually in the form of
- "Copyright 2008 Foo"
- -d,--dir Used to indicate source when using
- --exclude
- -e,--exclude <expression> Excludes files matching wildcard
- <expression>. Note that --dir is required
- when using this parameter. Allows multiple
- arguments.
- -E,--exclude-file <fileName> Excludes files matching regular expression
- in <file> Note that --dir is required when
- using this parameter.
- -f,--force Forces any changes in files to be written
- directly to the source files (i.e. new
- files are not created).
- -h,--help Print help for the RAT command line
- interface and exit.
- --licenses <arg> File names or URLs for license definitions
- --list-families <arg> List the defined license families (default
- is none). Valid options are: all,
- approved, none.
- --list-licenses <arg> List the defined licenses (default is
- none). Valid options are: all, approved,
- none.
- --log-level <level> sets the log level. Valid options are:
- DEBUG, INFO, WARN, ERROR, OFF
- --no-default-licenses Ignore default configuration. By default
- all approved default licenses are used
- -o,--out <arg> Define the output file where to write a
- report to (default is System.out).
- -s,--stylesheet <arg> XSLT stylesheet to use when creating the
- report. Not compatible with -x. Either
- an external xsl file may be specified or
- one of the internal named sheets:
- plain-rat (default), missing-headers, or
- unapproved-licenses
- --scan-hidden-directories Scan hidden directories
- -x,--xml Output the report in raw XML format. Not
- compatible with -s
+
+====== Available Options ======
+ -a (deprecated) Add the default license header to any file with an unknown license. Use '-A'
+ or ---addLicense instead.
+ -A,--addLicense Add the default license header to any file with an unknown license that is not in the
+ exclusion list. By default new files will be created with the license header, to force the
+ modification of existing files use the --force option.
+ --archive <ProcessingType> Specifies the level of detail in ARCHIVE reporting. (default is NOTIFICATION)
+ -c,--copyright <arg> The copyright message to use in the license headers, usually in the form of "Copyright 2008
+ Foo"
+ -d,--dir <DirOrArchive> (deprecated, use '--') Used to indicate source when using --exclude.
+ --dry-run If set do not update the files but generate the reports.
+ -e,--exclude <Expression> Excludes files matching wildcard <expression>. May be followed by multiple arguments. Note
+ that '--' or a following option is required when using this parameter.
+ -E,--exclude-file <FileOrURI> Excludes files matching regular expression in the input file.
+ -f,--force Forces any changes in files to be written directly to the source files (i.e. new files are
+ not created).
+ -h,--help Print help for the RAT command line interface and exit.
+ --licenses <FileOrURI> File names or URLs for license definitions
+ --list-families <LicenseFilter> List the defined license families (default is NONE). Valid options are: ALL, APPROVED, NONE
+ --list-licenses <LicenseFilter> List the defined licenses (default is NONE). Valid options are: ALL, APPROVED, NONE
+ --log-level <LogLevel> sets the log level.
+ --no-default-licenses Ignore default configuration. By default all approved default licenses are used
+ -o,--out <arg> Define the output file where to write a report to (default is System.out).
+ -s,--stylesheet <StyleSheet> XSLT stylesheet to use when creating the report. Not compatible with -x. Either an
+ external xsl file may be specified or one of the internal named sheets: plain-rat (default),
+ missing-headers, or unapproved-licenses
+ --scan-hidden-directories Scan hidden directories
+ -x,--xml Output the report in raw XML format. Not compatible with -s
+
+====== Argument Types ======
+
+<DirOrArchive>
+ A directory or archive file to scan
+
+<Expression>
+ A wildcard file matching pattern. example: *-test-*.txt
+
+<FileOrURI>
+ A file name or URI
+
+<LicenseFilter>
+ A defined filter for the licenses to include. Valid values: ALL, APPROVED, NONE.
+
+<LogLevel>
+ The log level to use. Valid values DEBUG, INFO, WARN, ERROR, OFF.
+
+<ProcessingType>
+ Specifies how to process file types. Valid values are:
+ NOTIFICATION: List file as present
+ PRESENCE: List any licenses found
+ ABSENCE: List licenses found and any unknown licences
+
+<StyleSheet>
+ Either an external xsl file or maybe one of the internal named sheets. Internal sheets are:
+ plain-rat: The default style
+ missing-headers: Produces a report of files that are missing headers
+ unapproved-licenses: Produces a report of the files with unapproved licenses.
+
+====== Notes ======
+
+1. Rat highlights possible issues.
+2. Rat reports require interpretation.
+3. Rat often requires some tuning before it runs well against a project.
+4. Rat relies on heuristics: it may miss issues
+
+------------------------------------------+
** Styling output
diff --git a/pom.xml b/pom.xml
index e8669cc..f96930b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -110,6 +110,11 @@
<version>1.26.1</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ <version>1.12.0</version>
+ </dependency>
+ <dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.10.2</version>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 7449d6d..f9c6734 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -72,6 +72,16 @@
</release>
-->
<release version="0.17-SNAPSHOT" date="xxxx-yy-zz" description="Current SNAPSHOT - release to be done">
+ <action issue="RAT-372" type="add" dev="claudenw">
+ Added ability to process archive files within a project to look for license files. This necessitated an addition
+ of a command line option "archive" to limit specify the level of detail in the archive report. See command line
+ help for more details. By default, there is no change in the reporting and only the presence of archives are reported.
+
+ This change also marked as deprecated the "-a", "--dir" and command line options.
+
+ This change also marks an architecture change from processing Files to processing Documents in order to facilitate
+ processing nested files in archives.
+ </action>
<action issue="RAT-314" type="add" dev="pottlinger">
Add integration test for new default exclude .mvn, that was introduced with v0.16.
</action>
@@ -90,14 +100,16 @@
<action issue="RAT-147" type="fix" dev="claudenw">
Change to detect non UTF-8 text files as text not binary.
</action>
- <action issue="RAT-150" type="add" dev="claudenw">
- Switch to Apache Tika to detect file types.
+
+ <action issue="RAT-150" type="fix" dev="claudenw">
+ Switch to Tika to detect file types. This will result in more file types being properly categorized and may
+ result in some failures where the scans previously did not fail because we now properly check all text files.
</action>
<action issue="RAT-211" type="fix" dev="claudenw">
Generated rat-output.xml is now well-formed, even if BinaryGuesser fails or there is XML content
in the sample element.
</action>
- <action issue="RAT-368" type="update" dev="claudenw">
+ <action issue="RAT-368" type="remove" dev="claudenw">
Removed ReportFailedRuntimeException, ReportTransformer, RatReportAnalysisResultException, MimeTyper, ToNameTransformer,
UnsuitableDocumentException, ReportTransformerTest, and ToNameTransformerTest as they are no longer used in the codebase.
Note: FullTextMatchingeLicense and SimplePatternBasedLicense will be removed in 0.18.0
@@ -110,12 +122,15 @@
</action>
<action issue="RAT-366" type="update" dev="claudenw">
Switch to processing header matches in one call rather than line by line.
+
+ This change also resulted in the possibility of multiple licenses being detected and reported. forcing a change in the
+ XML ouptut. XML schema was developed for the output.
</action>
<action issue="RAT-333" type="fix" dev="claudenw">
Fix if --force option is used executable bit is not set properly on newly created/license-augmented file.
</action>
<action issue="RAT-345" type="update" dev="pottlinger" due-to="Niels Basjes">
- Update gitignore-reader from 1.4.0 to 1.5.1 to fetch changes resulting from fixes of RAT-362.
+ Update gitignore-reader from 1.4.0 to 1.5.1 to fetch changes resulting from fixes of RAT-362.
</action>
<action issue="RAT-362" type="fix" dev="pottlinger" due-to="Niels Basjes, Arnout Engelen">
Gitignore parsing fails when excluded element is part of the current base directory.
@@ -186,28 +201,28 @@
Fix double output by deleting any existing RAT report before writing a fresh file during plugin runs.
</action>
<action issue="RAT-339" type="update" dev="pottlinger" due-to="dependabot">
- Update mavenPluginPluginVersion from 3.10.2 to 3.11.0 and introduce goalPrefix in plugin configuration.
+ Update mavenPluginPluginVersion from 3.10.2 to 3.11.0 and introduce goalPrefix in plugin configuration.
</action>
<action issue="RAT-339" type="update" dev="pottlinger" due-to="dependabot">
- Update junit-platform-runner from 1.8.1 to 1.10.1.
+ Update junit-platform-runner from 1.8.1 to 1.10.1.
</action>
<action issue="RAT-339" type="update" dev="pottlinger" due-to="dependabot">
- Update junit from 5.10.0 to 5.10.1.
+ Update junit from 5.10.0 to 5.10.1.
</action>
<action issue="RAT-339" type="update" dev="pottlinger" due-to="dependabot">
- Update actions/cache from 3.3.2 to 4.0.0.
+ Update actions/cache from 3.3.2 to 4.0.0.
</action>
<action issue="RAT-339" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-surefire-plugin from 3.2.3 to 3.2.5.
+ Update maven-surefire-plugin from 3.2.3 to 3.2.5.
</action>
<action issue="RAT-339" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-jxr-plugin from 3.3.1 to 3.3.2.
+ Update maven-jxr-plugin from 3.3.1 to 3.3.2.
</action>
<action issue="RAT-339" type="update" dev="pottlinger" due-to="dependabot">
- Update slf4j-simple from 2.0.9 to 2.0.11.
+ Update slf4j-simple from 2.0.9 to 2.0.11.
</action>
<action issue="RAT-339" type="update" dev="pottlinger" due-to="dependabot">
- Update assertj-core from 3.24.2 to 3.25.1.
+ Update assertj-core from 3.24.2 to 3.25.1.
</action>
</release>
<release version="0.16" date="2023-12-28" description=
@@ -225,79 +240,79 @@
Update actions/cache from 3.0.11 to 3.3.2
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update actions/checkout from 3 to 4.
+ Update actions/checkout from 3 to 4.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update mockito-core from 4.7.0 to 4.11.0, newer versions 5.x cannot be applied due to our JDK8-compatibility restriction.
+ Update mockito-core from 4.7.0 to 4.11.0, newer versions 5.x cannot be applied due to our JDK8-compatibility restriction.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update plexus-utils from 3.4.2 to 3.5.1, versions 4.x are for upcoming Maven4 and must not be applied here.
+ Update plexus-utils from 3.4.2 to 3.5.1, versions 4.x are for upcoming Maven4 and must not be applied here.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-plugin-version from 3.6.4 to 3.8.2.
+ Update maven-plugin-version from 3.6.4 to 3.8.2.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update wagon-ssh from 3.5.2 to 3.5.3.
+ Update wagon-ssh from 3.5.2 to 3.5.3.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update Ant from 1.10.12 to 1.10.14.
+ Update Ant from 1.10.12 to 1.10.14.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
Update ASF parent pom from 27 to 31 and update multiple maven plugin versions implicitly (surefire, release, project-info, enforcer, jxr).
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update doxiaVersion from 1.11.1 to 1.12.0.
+ Update doxiaVersion from 1.11.1 to 1.12.0.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-shared-utils from 3.3.4 to 3.4.2.
+ Update maven-shared-utils from 3.3.4 to 3.4.2.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update org.slf4j:slf4j-simple from 1.7.36 to 2.0.9.
+ Update org.slf4j:slf4j-simple from 1.7.36 to 2.0.9.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update commons-lang3 from 3.5 to 3.14.0.
+ Update commons-lang3 from 3.5 to 3.14.0.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
Update commons-compress from 1.21 to 1.25.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update commons-io from 2.11.0 to 2.15.1.
+ Update commons-io from 2.11.0 to 2.15.1.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update commons-cli from 1.5.0 to 1.6.0.
+ Update commons-cli from 1.5.0 to 1.6.0.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-pmd-plugin from 3.18.0 to 3.21.2.
+ Update maven-pmd-plugin from 3.18.0 to 3.21.2.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
Update maven-dependency-plugin from 3.3.0 to 3.6.1.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-compiler-plugin from 3.10.1 to 3.12.1.
+ Update maven-compiler-plugin from 3.10.1 to 3.12.1.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-javadoc-plugin from 3.4.1 to 3.6.3.
+ Update maven-javadoc-plugin from 3.4.1 to 3.6.3.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-release-plugin from 2.5.3 to 3.0.1.
+ Update maven-release-plugin from 2.5.3 to 3.0.1.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-enforcer-plugin from 3.1.0 to 3.4.1.
+ Update maven-enforcer-plugin from 3.1.0 to 3.4.1.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update extra-enforcer-rules from 1.6.1 to 1.7.0
+ Update extra-enforcer-rules from 1.6.1 to 1.7.0
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-release-plugin from 2.5.3 to 3.0.1.
+ Update maven-release-plugin from 2.5.3 to 3.0.1.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update animal-sniffer-maven-plugin from 1.22 to 1.23.
+ Update animal-sniffer-maven-plugin from 1.22 to 1.23.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-project-info-reports-plugin from 3.4.1 to 3.5.0.
+ Update maven-project-info-reports-plugin from 3.4.1 to 3.5.0.
</action>
<action issue="RAT-311" type="update" dev="pottlinger" due-to="dependabot">
- Update maven-surefire-plugin from 3.2.2 to 3.2.3.
+ Update maven-surefire-plugin from 3.2.2 to 3.2.3.
</action>
<action issue="RAT-326" type="fix" dev="pottlinger">
Fix existing javadoc build errors and add javadoc generation to existing GithubActions to not introduce build errors via merge requests.
diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm
index 236cab0..a0b40c0 100644
--- a/src/site/apt/index.apt.vm
+++ b/src/site/apt/index.apt.vm
@@ -72,7 +72,9 @@
* Add a new {{{./matcher_def.html}Matcher definition}}. Requires Java expertise.
- * Add a new definition format. Requires Java expertice as well as expertise with the format.
+ * Add a new definition format. Requires Java expertise as well as expertise with the format.
+
+ * Write a new {{{./xslt_def.html}output report}}. Requires XSLT knowledge.
** Who Develops Rat?
@@ -136,6 +138,8 @@
These stylesheets can be specified using options in the command line, Maven or Ant clients.
+ In addition, new {{{/xslt_def.html}stylesheets may be developed}} and applied to create new reports.
+
* Checking Out Rat
Quick start
diff --git a/src/site/apt/xslt_def.apt.vm b/src/site/apt/xslt_def.apt.vm
new file mode 100644
index 0000000..79de4d4
--- /dev/null
+++ b/src/site/apt/xslt_def.apt.vm
@@ -0,0 +1,86 @@
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~ Licensed to the Apache Software Foundation (ASF) under one or more
+~~ contributor license agreements. See the NOTICE file distributed with
+~~ this work for additional information regarding copyright ownership.
+~~ The ASF licenses this file to You under the Apache License, Version 2.0
+~~ (the "License"); you may not use this file except in compliance with
+~~ the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing, software
+~~ distributed under the License is distributed on an "AS IS" BASIS,
+~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~~ See the License for the specific language governing permissions and
+~~ limitations under the License.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ --------------------------
+ How to define new Rat reports
+ --------------------------
+
+How to define new Rat reports
+
+ All Rat reports are {{{https://www.w3.org/TR/xslt-30/}XSLT stylesheets}} that transform the XML output. The {{{https://www.w3.org/TR/xmlschema11-1/}schema}} for the XML output can be found in the
+ {{{https://gitbox.apache.org/repos/asf/creadur-rat/blob/master/apache-rat-core/src/main/resources/org/apache/rat/rat-report.xsd}
+core resources rat-report.xsd file.}}
+
+ There are three internal reports in the same directory that can also be used as examples:
+
+ * {{{https://gitbox.apache.org/repos/asf/creadur-rat/blob/master/apache-rat-core/src/main/resources/org/apache/rat/plain-rat.xsl}
+plain-rat.xsl}}: The default report.
+
+ * {{{https://gitbox.apache.org/repos/asf/creadur-rat/blob/master/apache-rat-core/src/main/resources/org/apache/rat/missing-headers.xsl}
+missing-headers.xsl}}: A report that lists files that do not have headers.
+
+ * {{{https://gitbox.apache.org/repos/asf/creadur-rat/blob/master/apache-rat-core/src/main/resources/org/apache/rat/unapproved-licenses.xsl}
+unapproved-licenses.xsl}}: A report that lists files with unapproved licenses.
+
+* The Report XML
+
+ The apache-rat sub-module has an example of
+ {{{https://gitbox.apache.org/repos/asf/creadur-rat/blob/master/apache-rat/src/site/examples/rat-report.txt}the Rat report XML file.}}
+
+** <<<rat-report>>> Element
+
+ The XML document starts with a <<<rat-report>>> element that has a <<<timestamp>>> attribute that contains the date and time the Rat report was
+ created. The <<<rat-report>>> only contains <<<resource>>> elements.
+
+** <<<resource>>> Element
+
+ There is one <<<resource>>> element for every file that was processed. The <<<resource>>> may contain <<<license>>> and <<<sample>>> child elements.
+ It has two attributes:
+
+ * <<<name>>>: The name of the file.
+
+ * <<<type>>>: The document type. This is one of the <<<Document.Type>>> enum values. The value is always in lower case. For a complete
+ list see the {{{https://gitbox.apache.org/repos/asf/creadur-rat/blob/master/apache-rat/src/main/java/org/apache/rat/api/Document.java}Document.java}}
+ file for a complete list of document types.
+
+** <<<license>>> Element
+
+ The <<<license>>> element is only found as a child of a <<<resource>>> element and may have a <<<notes>>> child element. The <<<license>>> element has four elements:
+
+ * <<<approval>>>: Specifies whether the license is approved. Values are restricted to 'true' and 'false'.
+
+ * <<<family>>>: The license family code. This is always 5 characters long and may have spaces at the end.
+
+ * <<<id>>>: The license id. This is often the same as the license family code with trailing spaces removed, but may be other values.
+ It is guaranteed to be unique within licenses.
+
+ * <<<name>>>: The name of the license. This is the human readable name that was provided when the license was defined.
+
+** <<<sample>>> Element
+
+ The <<<sample>>> element contains a <<<CDATA>>> block comprising the text that was processed when the <<<resource>>> was processed.
+
+** <<<notes>>> Element
+
+ The <<<notes>>> element contains a <<<CDATA>>> block comprising the text of any notes about the license that were provided when the license was defined.
+
+* How to use the report
+
+ Once an XSLT stylesheet has been developed it can be tested by running Rat and providing the full path to the XSLT stylesheet as the stylesheet
+ argument for the client being used. See Running Rat from the {{{./apache-rat/index.html}Command line}},
+ {{{./apache-rat-plugin/index.html}Maven}}, or
+ {{{./apache-rat-tasks/index.html}Ant}} for details.