This is an automated email from the ASF dual-hosted git repository.

claude pushed a commit to branch feature/restructure
in repository https://gitbox.apache.org/repos/asf/creadur-rat.git

commit e77f7088b4c16d38cd7e430d9719d551d1c683b2
Author: Claude Warren <[email protected]>
AuthorDate: Sat Mar 7 15:06:01 2026 +0000

    cleaned up tests
---
 .../rat/ant/ResourceCollectionContainer.java       |   2 +-
 apache-rat-core/pom.xml                            |   2 +-
 .../main/java/org/apache/rat/commandline/Arg.java  |   4 +-
 .../apache/rat/report/claim/ClaimStatistic.java    |  11 ++-
 .../java/org/apache/rat/ui/ArgumentTracker.java    |   5 +-
 apache-rat-maven-parent/plugin/pom.xml             |  50 ++++++----
 .../java/org/apache/rat/maven/AbstractRatMojo.java |  25 ++---
 .../java/org/apache/rat/maven/RatCheckMojo.java    |  17 +++-
 .../java/org/apache/rat/maven/RatReportMojo.java   |  20 ++--
 apache-rat-maven-parent/pom.xml                    |  22 ++++-
 apache-rat-maven-parent/spotbugs-ignore.xml        |   5 +-
 apache-rat-maven-parent/tools/pom.xml              |   2 +-
 .../java/org/apache/rat/maven/MavenOption.java     | 105 +++++----------------
 .../apache/rat/maven/MavenOptionCollection.java    |  79 +++++++++++++++-
 .../java/org/apache/rat/maven/PropertyReader.java  |  17 +++-
 .../java/org/apache/rat/maven/package-info.java    |   2 +-
 .../org/apache/rat/maven/tools/CodeGenerator.java  |  71 ++++++++------
 .../org/apache/rat/maven/tools/TestGenerator.java  |  91 +++++++++++-------
 .../org/apache/rat/maven/tools/AbstractMaven.vm    |  10 +-
 .../apache/rat/maven/tools/AbstractMavenFunc.vm    |   4 +-
 .../rat/maven/MavenOptionCollectionTest.java       |  49 +++++++++-
 .../org/apache/rat/maven/PropertyReaderTest.java   |  13 +++
 .../apache/rat/maven/tools/CodeGeneratorTest.java  |  34 +++++++
 .../apache/rat/maven/tools/TestGeneratorTest.java  |  48 ++++++++++
 24 files changed, 474 insertions(+), 214 deletions(-)

diff --git 
a/apache-rat-ant-parent/apache-rat-tasks/src/main/java/org/apache/rat/ant/ResourceCollectionContainer.java
 
b/apache-rat-ant-parent/apache-rat-tasks/src/main/java/org/apache/rat/ant/ResourceCollectionContainer.java
index 7d5b237b..c1521994 100644
--- 
a/apache-rat-ant-parent/apache-rat-tasks/src/main/java/org/apache/rat/ant/ResourceCollectionContainer.java
+++ 
b/apache-rat-ant-parent/apache-rat-tasks/src/main/java/org/apache/rat/ant/ResourceCollectionContainer.java
@@ -59,7 +59,7 @@ class ResourceCollectionContainer implements IReportable {
     }
 
     @Override
-    public DocumentName getName() {
+    public DocumentName name() {
         return name;
     }
 }
diff --git a/apache-rat-core/pom.xml b/apache-rat-core/pom.xml
index 79861a25..fb952f78 100644
--- a/apache-rat-core/pom.xml
+++ b/apache-rat-core/pom.xml
@@ -128,7 +128,7 @@
                 <artifactId>spotbugs-maven-plugin</artifactId>
                 <configuration>
                     <excludeFilterFile>spotbugs-ignore.xml</excludeFilterFile>
-                    <maxAllowedViolations>47</maxAllowedViolations>
+                    <maxAllowedViolations>90</maxAllowedViolations>
                 </configuration>
             </plugin>
             <plugin>
diff --git a/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java 
b/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
index 6f382ea0..7789ad8c 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
@@ -21,7 +21,6 @@ package org.apache.rat.commandline;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.lang.reflect.Array;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
@@ -40,7 +39,6 @@ import org.apache.commons.cli.OptionGroup;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.function.IOSupplier;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.rat.ConfigurationException;
 import org.apache.rat.Defaults;
@@ -876,7 +874,7 @@ public enum Arg {
                 context.getConfiguration().setOut(file);
             } catch (ParseException e) {
                 context.logParseException(e, OUTPUT_FILE.getSelected(), 
"System.out");
-                context.getConfiguration().setOut((IOSupplier<OutputStream>) 
null);
+                
context.getConfiguration().setOut(ReportConfiguration.SYSTEM_OUT);
             }
         }
 
diff --git 
a/apache-rat-core/src/main/java/org/apache/rat/report/claim/ClaimStatistic.java 
b/apache-rat-core/src/main/java/org/apache/rat/report/claim/ClaimStatistic.java
index 4237586f..d47f2e5b 100644
--- 
a/apache-rat-core/src/main/java/org/apache/rat/report/claim/ClaimStatistic.java
+++ 
b/apache-rat-core/src/main/java/org/apache/rat/report/claim/ClaimStatistic.java
@@ -156,6 +156,15 @@ public class ClaimStatistic {
         counterMap.compute(counter, (k, v) -> v == null ? new 
IntCounter().increment(value) : v.increment(value));
     }
 
+    /**
+     * Increments the counts for the counter.
+     * @param counter the counter to increment.
+     * @param value the value to increment the counter by.
+     */
+    public void setCounter(final Counter counter, final int value) {
+        counterMap.put(counter, new IntCounter().increment(value));
+    }
+
     /**
      * Gets the counts for the Document.Type.
      * @param documentType the Document.Type to get the counter for.
@@ -391,7 +400,7 @@ public class ClaimStatistic {
             
XMLConfigurationReader.nodeListConsumer(document.getElementsByTagName("counter"),
 node -> {
                 Map<String, String> attributes = 
XMLConfigurationReader.attributes(node);
                 Counter type = Counter.valueOf(attributes.get("name"));
-                incCounter(type, Integer.parseInt(attributes.get("count")));
+                setCounter(type, Integer.parseInt(attributes.get("count")));
             });
         }
     }
diff --git 
a/apache-rat-core/src/main/java/org/apache/rat/ui/ArgumentTracker.java 
b/apache-rat-core/src/main/java/org/apache/rat/ui/ArgumentTracker.java
index 1e320690..460b1030 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/ui/ArgumentTracker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/ui/ArgumentTracker.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.function.BiConsumer;
 import java.util.stream.Collectors;
 
@@ -154,8 +155,8 @@ public final class ArgumentTracker {
      * @param key the key for the map.
      * @return the list of values for the key or {@code null} if not set.
      */
-    public List<String> getArg(final String key) {
-        return args.get(key);
+    public Optional<List<String>> getArg(final String key) {
+        return Optional.ofNullable(args.get(key));
     }
 
     /**
diff --git a/apache-rat-maven-parent/plugin/pom.xml 
b/apache-rat-maven-parent/plugin/pom.xml
index 7e3a404d..877eaea8 100644
--- a/apache-rat-maven-parent/plugin/pom.xml
+++ b/apache-rat-maven-parent/plugin/pom.xml
@@ -32,6 +32,7 @@
     <maven>${mavenMinVersion}</maven>
   </prerequisites>
   <properties>
+    <coreVersion>1.0.0-SNAPSHOT</coreVersion>
     <currentVersion>${project.version}</currentVersion>
     <doxiaVersion>2.0.0</doxiaVersion>
   </properties>
@@ -189,32 +190,32 @@
             </goals>
             <phase>generate-sources</phase>
             <configuration>
-              <mainClass>org.apache.rat.maven.CodeGenerator</mainClass>
+              <mainClass>org.apache.rat.maven.tools.CodeGenerator</mainClass>
               <arguments>
                 <argument>-p</argument>
                 <argument>${project.build.sourceDirectory}</argument>
               </arguments>
             </configuration>
           </execution>
-          <execution>
-            <id>generate-rat-tests</id>
-            <goals>
-              <goal>java</goal>
-            </goals>
-            <phase>generate-test-sources</phase>
-            <configuration>
-              <skip>true</skip>
-              <mainClass>org.apache.rat.maven.TestGenerator</mainClass>
-              <arguments>
-                <argument>-t</argument>
-                <argument>${project.build.testSourceDirectory}</argument>
-                <argument>-r</argument>
-                
<argument>${project.build.testSourceDirectory}/../resources</argument>
-                <argument>-p</argument>
-                <argument>org.apache.rat.maven</argument>
-              </arguments>
-            </configuration>
-          </execution>
+<!--          <execution>-->
+<!--            <id>generate-rat-tests</id>-->
+<!--            <goals>-->
+<!--              <goal>java</goal>-->
+<!--            </goals>-->
+<!--            <phase>generate-test-sources</phase>-->
+<!--            <configuration>-->
+<!--              <skip>true</skip>-->
+<!--              
<mainClass>org.apache.rat.maven.tools.TestGenerator</mainClass>-->
+<!--              <arguments>-->
+<!--                <argument>-t</argument>-->
+<!--                
<argument>${project.build.testSourceDirectory}</argument>-->
+<!--                <argument>-r</argument>-->
+<!--                
<argument>${project.build.testSourceDirectory}/../resources</argument>-->
+<!--                <argument>-p</argument>-->
+<!--                <argument>org.apache.rat.maven</argument>-->
+<!--              </arguments>-->
+<!--            </configuration>-->
+<!--          </execution>-->
           <execution>
             <id>Initial site generation</id>
             <phase>pre-site</phase>
@@ -249,6 +250,8 @@
           
<cloneProjectsTo>${project.build.directory}/invoker_target</cloneProjectsTo>
           
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
           <addTestClassPath>true</addTestClassPath>
+<!--          
<extraArtifacts>org.apache.rat:apache-rat-core-tests:${coreVerson}:jar-->
+<!--            </extraArtifacts>-->
           <settingsFile>src/it/settings.xml</settingsFile>
           <postBuildHookScript>verify</postBuildHookScript>
         </configuration>
@@ -329,6 +332,7 @@
     <dependency>
       <groupId>org.apache.rat</groupId>
       <artifactId>apache-rat-core</artifactId>
+      <version>${coreVersion}</version>
     </dependency>
     <!-- rat tools in test scope so that it does not get bundled into the 
plugin -->
 <!--    <dependency>-->
@@ -339,6 +343,7 @@
     <dependency>
       <groupId>org.apache.rat</groupId>
       <artifactId>apache-rat-core-tests</artifactId>
+      <version>${coreVersion}</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
@@ -361,6 +366,11 @@
       <artifactId>junit-jupiter-params</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.maven.shared</groupId>
+      <artifactId>maven-invoker</artifactId>
+      <version>3.3.0</version>
+    </dependency>
     <dependency>
       <groupId>org.apache.maven.plugin-tools</groupId>
       <artifactId>maven-plugin-annotations</artifactId>
diff --git 
a/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/AbstractRatMojo.java
 
b/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/AbstractRatMojo.java
index 1f28ad31..24d59339 100644
--- 
a/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/AbstractRatMojo.java
+++ 
b/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/AbstractRatMojo.java
@@ -24,20 +24,20 @@ import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.ParseException;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.project.MavenProject;
-import org.apache.rat.OptionCollection;
+import org.apache.rat.OptionCollectionParser;
 import org.apache.rat.ReportConfiguration;
 import org.apache.rat.commandline.Arg;
 import org.apache.rat.commandline.ArgumentContext;
 import org.apache.rat.document.DocumentName;
 import org.apache.rat.document.FileDocument;
 import org.apache.rat.license.ILicense;
+import org.apache.rat.ui.ArgumentTracker;
 import org.apache.rat.utils.DefaultLog;
 import org.apache.rat.utils.Log;
 import org.apache.rat.walker.DirectoryWalker;
@@ -121,12 +121,7 @@ public abstract class AbstractRatMojo extends 
AbstractMaven {
     protected List<String> getValues(final Arg arg) {
         List<String> result = new ArrayList<>();
         for (Option option : arg.group().getOptions()) {
-            if (option.getLongOpt() != null) {
-                List<String> args = 
argumentTracker.getArg(option.getLongOpt());
-                if (args != null) {
-                    result.addAll(args);
-                }
-            }
+            
argumentTracker.getArg(ArgumentTracker.extractKey(option)).ifPresent(result::addAll);
         }
         return result;
     }
@@ -236,13 +231,12 @@ public abstract class AbstractRatMojo extends 
AbstractMaven {
 
     protected ReportConfiguration getConfiguration() throws 
MojoExecutionException {
         Log log = DefaultLog.getInstance();
+        OptionCollectionParser optionParser = new 
OptionCollectionParser(mavenOptionCollection);
         if (reportConfiguration == null) {
             try {
                 if (getLog().isDebugEnabled()) {
                     log.debug("Start BaseRatMojo Configuration options");
-                    for (Map.Entry<String, List<String>> entry : 
argumentTracker.entrySet()) {
-                        log.debug(format(" * %s %s", entry.getKey(), 
String.join(", ", entry.getValue())));
-                    }
+                    argumentTracker.apply((k, v) -> log.debug(format(" * %s 
%s", k, String.join(", ", v))));
                     log.debug("End BaseRatMojo Configuration options");
                 }
 
@@ -250,11 +244,12 @@ public abstract class AbstractRatMojo extends 
AbstractMaven {
                 removeKey(Arg.HELP_LICENSES);
                 setIncludeExclude();
 
-                ArgumentContext ctxt = OptionCollection.parseCommands(basedir, 
argumentTracker.args().toArray(new String[0]));
+                ArgumentContext ctxt = optionParser.parseCommands(basedir, 
argumentTracker.args().toArray(new String[0]));
                 DocumentName dirName = DocumentName.builder(basedir).build();
-                ctxt.getConfiguration().addSource(new DirectoryWalker(new 
FileDocument(dirName, basedir,
-                        
ctxt.getConfiguration().getDocumentExcluder(dirName))));
-
+                if 
(argumentTracker.getArg(ArgumentTracker.extractKey(Arg.SOURCE.option())).isEmpty())
 {
+                    ctxt.getConfiguration().addSource(new DirectoryWalker(new 
FileDocument(dirName, basedir,
+                            
ctxt.getConfiguration().getDocumentExcluder(dirName))));
+                }
                 if (helpLicenses) {
                     new org.apache.rat.help.Licenses(ctxt.getConfiguration(), 
new PrintWriter(log.asWriter())).printHelp();
                 }
diff --git 
a/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/RatCheckMojo.java
 
b/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/RatCheckMojo.java
index af49134d..ed2345bf 100644
--- 
a/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/RatCheckMojo.java
+++ 
b/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/RatCheckMojo.java
@@ -41,12 +41,15 @@ import org.apache.rat.Reporter;
 import org.apache.rat.api.RatException;
 import org.apache.rat.commandline.Arg;
 import org.apache.rat.commandline.StyleSheets;
+import org.apache.rat.document.DocumentName;
 import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
 import org.apache.rat.report.claim.ClaimStatistic;
 import org.apache.rat.ui.ArgumentTracker;
 import org.apache.rat.utils.DefaultLog;
 import org.apache.rat.utils.FileUtils;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
 import static java.lang.String.format;
 
 /**
@@ -67,6 +70,7 @@ public final class RatCheckMojo extends AbstractRatMojo {
         super();
     }
 
+    @SuppressFBWarnings("EI_EXPOSE_REP")
     public Reporter.Output getOutput() {
         return output;
     }
@@ -103,6 +107,12 @@ public final class RatCheckMojo extends AbstractRatMojo {
             return;
         }
 
+        if (getLog().isDebugEnabled()) {
+            getLog().debug("ARG list -->");
+            argumentTracker.args().forEach(getLog()::debug);
+            getLog().debug("<-- ARG list");
+        }
+
         if (getValues(Arg.OUTPUT_FILE).isEmpty()) {
             
argumentTracker.setArg(ArgumentTracker.extractKey(Arg.OUTPUT_FILE.option()), 
"target/rat.txt");
         }
@@ -143,7 +153,7 @@ public final class RatCheckMojo extends AbstractRatMojo {
         FileUtils.mkDir(ratPath.toFile());
         Path xmlPath = ratPath.resolve("rat.xml");
         IOSupplier<OutputStream> outputStream = () -> 
Files.newOutputStream(xmlPath);
-        final IOSupplier<InputStream> stylesheet = 
StyleSheets.XML.getStyleSheet();
+        final IOSupplier<InputStream> stylesheet = 
StyleSheets.XML.getStyleSheet().ioSupplier();
         try {
             output.format(stylesheet, outputStream);
         } catch (RatException e) {
@@ -169,7 +179,7 @@ public final class RatCheckMojo extends AbstractRatMojo {
                     
!config.getClaimValidator().isValid(ClaimStatistic.Counter.UNAPPROVED, 
statistics.getCounter(ClaimStatistic.Counter.UNAPPROVED))) {
                 try {
                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    
output.format(StyleSheets.UNAPPROVED_LICENSES.getStyleSheet(), () -> baos);
+                    
output.format(StyleSheets.UNAPPROVED_LICENSES.getStyleSheet().ioSupplier(), () 
-> baos);
                     getLog().warn(baos.toString(StandardCharsets.UTF_8));
                 } catch (RuntimeException rte) {
                     throw rte;
@@ -202,7 +212,8 @@ public final class RatCheckMojo extends AbstractRatMojo {
     public File getRatTxtFile() throws MojoFailureException {
         List<String> args = getValues(Arg.OUTPUT_FILE);
         if (args != null) {
-            return new File(args.get(0));
+            DocumentName workDir = DocumentName.builder(basedir).build();
+            return workDir.resolve(args.get(0)).asFile();
         }
         throw new MojoFailureException("No output file specified");
     }
diff --git 
a/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/RatReportMojo.java
 
b/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/RatReportMojo.java
index 0b971b75..6cbb2482 100644
--- 
a/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/RatReportMojo.java
+++ 
b/apache-rat-maven-parent/plugin/src/main/java/org/apache/rat/maven/RatReportMojo.java
@@ -68,6 +68,8 @@ import org.eclipse.aether.repository.ArtifactRepository;
 import org.eclipse.aether.repository.RemoteRepository;
 import org.xml.sax.SAXException;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
 import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
 
 /**
@@ -139,6 +141,7 @@ public class RatReportMojo extends AbstractRatMojo 
implements MavenMultiPageRepo
      * @throws MojoExecutionException if an error occurs when generating the 
report
      * @see org.apache.maven.plugin.Mojo#execute()
      */
+    @SuppressFBWarnings("PATH_TRAVERSAL_IN")
     @Override
     public void execute() throws MojoExecutionException {
         if (!canGenerateReport()) {
@@ -245,6 +248,7 @@ public class RatReportMojo extends AbstractRatMojo 
implements MavenMultiPageRepo
      * @param locale the wanted locale to generate the report, could be null.
      * @throws MavenReportException if any
      */
+    @SuppressFBWarnings("EI_EXPOSE_REP2")
     @Override
     public void generate(final Sink sink, final SinkFactory sinkFactory, final 
Locale locale) throws MavenReportException {
         if (!canGenerateReport()) {
@@ -266,6 +270,7 @@ public class RatReportMojo extends AbstractRatMojo 
implements MavenMultiPageRepo
         }
     }
 
+    @SuppressFBWarnings("PATH_TRAVERSAL_IN")
     private void generateReportManually(final Locale locale) throws 
MavenReportException {
         try {
             File outputDir = new File(getOutputDirectory());
@@ -319,12 +324,12 @@ public class RatReportMojo extends AbstractRatMojo 
implements MavenMultiPageRepo
         return CATEGORY_PROJECT_REPORTS;
     }
 
+    @SuppressFBWarnings("PATH_TRAVERSAL_IN")
     @Override
     public File getReportOutputDirectory() {
         if (reportOutputDirectory == null) {
             reportOutputDirectory = new File(getOutputDirectory());
         }
-
         return reportOutputDirectory;
     }
 
@@ -334,6 +339,7 @@ public class RatReportMojo extends AbstractRatMojo 
implements MavenMultiPageRepo
         this.outputDirectory = reportOutputDirectory;
     }
 
+    @SuppressFBWarnings("PATH_TRAVERSAL_IN")
     protected String getOutputDirectory() {
         if (outputDirectory == null) {
             outputDirectory = new 
File(getProject().getModel().getReporting().getOutputDirectory());
@@ -369,14 +375,7 @@ public class RatReportMojo extends AbstractRatMojo 
implements MavenMultiPageRepo
      * Actions when closing the report.
      */
     protected void closeReport() {
-        getSink().close();
-    }
-
-    /**
-     * @return the sink used
-     */
-    public Sink getSink() {
-        return sink;
+        sink.close();
     }
 
     /**
@@ -400,6 +399,7 @@ public class RatReportMojo extends AbstractRatMojo 
implements MavenMultiPageRepo
         return !skip;
     }
 
+    @SuppressFBWarnings("XXE_DOCUMENT")
     Reporter.Output readReportFile() throws MavenReportException {
         File f = new File(outputDirectory, "RAT/rat.xml");
         try (InputStream inputStream = new FileInputStream(f)) {
@@ -440,7 +440,7 @@ public class RatReportMojo extends AbstractRatMojo 
implements MavenMultiPageRepo
         sink.link_();
         File f = new File(outputDirectory, ".rat.xhtml5");
         try {
-            readReportFile().format(StyleSheets.XHTML5.getStyleSheet(), () -> 
Files.newOutputStream(f.toPath()));
+            
readReportFile().format(StyleSheets.XHTML5.getStyleSheet().ioSupplier(), () -> 
Files.newOutputStream(f.toPath()));
             try (Reader reader = new 
InputStreamReader(Files.newInputStream(f.toPath()), StandardCharsets.UTF_8)) {
                 new Xhtml5Parser().parse(reader, sink);
             }
diff --git a/apache-rat-maven-parent/pom.xml b/apache-rat-maven-parent/pom.xml
index ae5451f3..50315421 100644
--- a/apache-rat-maven-parent/pom.xml
+++ b/apache-rat-maven-parent/pom.xml
@@ -35,7 +35,7 @@
     </prerequisites>
     <properties>
         <rat.version>1.0.0-SNAPSHOT</rat.version>
-        <currentVersion>${project.version}</currentVersion>
+        <rat.plugin.version>${project.version}</rat.plugin.version>
         <doxiaVersion>2.0.0</doxiaVersion>
         <mavenVersion>3.9.12</mavenVersion>
         <mavenPluginTestingVersion>3.4.0</mavenPluginTestingVersion>
@@ -43,7 +43,7 @@
     </properties>
     <modules>
         <module>tools</module>
-        <module>impl</module>
+        <module>plugin</module>
     </modules>
     <dependencyManagement>
         <dependencies>
@@ -80,6 +80,24 @@
     </dependencyManagement>
     <build>
         <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>properties-maven-plugin</artifactId>
+                <version>1.3.0</version>
+                <executions>
+                    <execution>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>write-project-properties</goal>
+                        </goals>
+                        <configuration>
+                            <outputFile>
+                                ${project.build.outputDirectory}/app.properties
+                            </outputFile>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
             <plugin>
                 <groupId>com.github.spotbugs</groupId>
                 <artifactId>spotbugs-maven-plugin</artifactId>
diff --git a/apache-rat-maven-parent/spotbugs-ignore.xml 
b/apache-rat-maven-parent/spotbugs-ignore.xml
index 39e672f5..1ffa7308 100644
--- a/apache-rat-maven-parent/spotbugs-ignore.xml
+++ b/apache-rat-maven-parent/spotbugs-ignore.xml
@@ -16,5 +16,8 @@
   limitations under the License.
 -->
 <FindBugsFilter>
-
+    <Match>
+        <Class name="org.apache.rat.plugin.HelpMojo"/>
+        <Bug pattern='XXE_DOCUMENT'/>
+    </Match>
 </FindBugsFilter>
diff --git a/apache-rat-maven-parent/tools/pom.xml 
b/apache-rat-maven-parent/tools/pom.xml
index 83e3c977..440e35cd 100644
--- a/apache-rat-maven-parent/tools/pom.xml
+++ b/apache-rat-maven-parent/tools/pom.xml
@@ -104,7 +104,7 @@
     <dependency>
       <groupId>org.apache.rat</groupId>
       <artifactId>apache-rat-core-tests</artifactId>
-      <scope>compile</scope>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.velocity.tools</groupId>
diff --git 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/MavenOption.java
 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/MavenOption.java
index 3766ce66..33c08df9 100644
--- 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/MavenOption.java
+++ 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/MavenOption.java
@@ -18,20 +18,9 @@
  */
 package org.apache.rat.maven;
 
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import java.util.function.Predicate;
-
 import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.collections4.map.UnmodifiableMap;
-import org.apache.commons.collections4.set.UnmodifiableSet;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.rat.commandline.Arg;
+import org.apache.commons.text.WordUtils;
 import org.apache.rat.ui.AbstractOption;
-import org.apache.rat.ui.OptionFactory;
 import org.apache.rat.utils.CasedString;
 
 import static java.lang.String.format;
@@ -40,60 +29,34 @@ import static java.lang.String.format;
  * A representation of a CLI option as a Maven option
  */
 public final class MavenOption extends AbstractOption<MavenOption> {
-
-    /** Default values for CLI options */
-    public static final UnmodifiableMap<Arg, String> DEFAULT_VALUES;
-    /** Set of CLI options that are not supported by Maven. */
-    public static final UnmodifiableSet<Option> UNSUPPORTED_SET;
-    /** A mapping of external name to internal name if not standard. */
-    public static final UnmodifiableMap<String, String> RENAME_MAP;
-    /** The additional options for the maven plugin */
-    static final Options ADDITIONAL_OPTIONS = new Options();
-    /** Filter to remove options not supported by Maven. */
-    static final Predicate<Option> MAVEN_FILTER;
-    /** The OptionFactory configuration for MavenOptions. */
-    public static final OptionFactory.Config<MavenOption> FACTORY_CONFIG;
-
-    static {
-        HashMap<String, String> map = new HashMap<>();
-        map.put("addLicense", "add-license");
-        RENAME_MAP = (UnmodifiableMap<String, String>) 
UnmodifiableMap.unmodifiableMap(map);
-        HashMap<Arg, String> values = new HashMap<>();
-        values.put(Arg.OUTPUT_FILE, "${project.build.directory}/rat.txt");
-        DEFAULT_VALUES = (UnmodifiableMap<Arg, String>) 
UnmodifiableMap.unmodifiableMap(values);
-
-        Set<Option> unsupportedOptions = new HashSet<>();
-        unsupportedOptions.addAll(Arg.DIR.group().getOptions());
-        unsupportedOptions.addAll(Arg.LOG_LEVEL.group().getOptions());
-        UNSUPPORTED_SET = (UnmodifiableSet<Option>) 
UnmodifiableSet.unmodifiableSet(unsupportedOptions);
-
-        MAVEN_FILTER =  option -> !(UNSUPPORTED_SET.contains(option) || 
option.getLongOpt() == null);
-        FACTORY_CONFIG = new OptionFactory.Config<>(MavenOption.MAVEN_FILTER, 
MavenOption::new, MavenOption.ADDITIONAL_OPTIONS);
-    }
+    /** The cased string version of the name */
+    private final CasedString casedName;
 
     /**
      * Constructor.
      *
      * @param option The CLI option
      */
-    public MavenOption(final Option option) {
-        super(option, createName(option));
+    MavenOption(final MavenOptionCollection collection, final Option option, 
final CasedString casedName) {
+        super(collection, option, 
casedName.toCase(CasedString.StringCase.CAMEL));
+        this.casedName = casedName;
     }
 
-    /**
-     * Creates the Maven element name for the specified option.
-     * @param option The option to process.
-     * @return the Maven based name in camel-case syntax.
-     */
-    static String createName(final Option option) {
-        String name = StringUtils.defaultIfEmpty(option.getLongOpt(), 
option.getOpt());
-        name = StringUtils.defaultIfEmpty(RENAME_MAP.get(name), 
name).toLowerCase(Locale.ROOT);
-        return new CasedString(CasedString.StringCase.KEBAB, 
name).toCase(CasedString.StringCase.CAMEL);
+    @Override
+    public String toString() {
+        return getName();
+    }
+
+    public String getMethodName() {
+        return "set" + casedName.toCase(CasedString.StringCase.PASCAL);
     }
 
     @Override
     protected String cleanupName(final Option option) {
-        return format("<%s>", createName(option));
+        if (option == this.option) {
+            return format("<%s>", this.name);
+        }
+        return format("<%s>", ((MavenOptionCollection) 
getOptionCollection()).createName(option));
     }
 
     @Override
@@ -101,49 +64,33 @@ public final class MavenOption extends 
AbstractOption<MavenOption> {
         return cleanupName(option);
     }
 
-    @Override
-    public Options getAdditionalOptions() {
-        return ADDITIONAL_OPTIONS;
-    }
-
-    @Override
-    public String getDefaultValue() {
-        Arg arg = Arg.findArg(option);
-        String result = DEFAULT_VALUES.get(arg);
-        if (result == null) {
-            result = arg.defaultValue();
-        }
-        return result;
-    }
 
     @Override
     public String getExample() {
-        if (UNSUPPORTED_SET.contains(option)) {
-            return "-- not supported --";
+        if (hasArgs()) {
+            return getExample(new String[]{getArgName() + "1", getArgName() + 
"2"});
         }
         if (hasArg()) {
-            return format("<%1$s>%2$s</%1$s>", getName(), getArgName());
-        } else {
-            return format("<%s />", getName());
+            return getExample(getArgName());
         }
+            return getExample("");
     }
 
-    public String getExample(final String[] args) {
-        StringBuilder sb = new StringBuilder("<").append(getName());
+    public String getExample(final String... args) {
+        StringBuilder sb = new StringBuilder(String.format("<%s>", getName()));
         if (hasArg()) {
-            sb.append(">");
             if (hasArgs()) {
                 sb.append(System.lineSeparator());
                 for (String arg : args) {
-                    sb.append(String.format("  <%1$s>%2$s</%1$s>%n", 
getArgName(), arg));
+                    sb.append(String.format("  <%1$s>%2$s</%1$s>%n", 
WordUtils.uncapitalize(getArgName()), arg));
                 }
             } else {
                 sb.append(args[0]);
             }
-            sb.append("</").append(getName()).append(">");
         } else {
-            sb.append("/>");
+            sb.append(Boolean.TRUE);
         }
+        sb.append("</").append(getName()).append(">");
         return sb.toString();
     }
 }
diff --git 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/MavenOptionCollection.java
 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/MavenOptionCollection.java
index 7af662d8..eb36976f 100644
--- 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/MavenOptionCollection.java
+++ 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/MavenOptionCollection.java
@@ -1,4 +1,81 @@
 package org.apache.rat.maven;
 
-public class MavenOptionCollection {
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.collections4.map.UnmodifiableMap;
+import org.apache.commons.collections4.set.UnmodifiableSet;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rat.commandline.Arg;
+import org.apache.rat.ui.AbstractOptionCollection;
+import org.apache.rat.ui.ArgumentTracker;
+import org.apache.rat.utils.CasedString;
+
+public class MavenOptionCollection extends 
AbstractOptionCollection<MavenOption> {
+    /** Set of CLI options that are not supported by Maven. */
+    private static final UnmodifiableSet<Option> UNSUPPORTED_OPTIONS;
+    /** Set of Additional options defined for Maven */
+    private static final Options ADDITIONAL_OPTIONS;
+    /** mapping of standard name to non-conflicting name. */
+    private static final Map<String, String> RENAME_MAP;
+    /** mapping of option to default values */
+    private final Map<Option, String> defaultOverride;
+
+    static {
+        Map<String, String> map = new HashMap<>();
+        map.put("addLicense", "add-license");
+        RENAME_MAP = (UnmodifiableMap<String, String>) 
UnmodifiableMap.unmodifiableMap(map);
+        Set<Option> unsupportedOptions = new HashSet<>();
+        unsupportedOptions.addAll(Arg.DIR.group().getOptions());
+        unsupportedOptions.addAll(Arg.LOG_LEVEL.group().getOptions());
+        UNSUPPORTED_OPTIONS = (UnmodifiableSet<Option>) 
UnmodifiableSet.unmodifiableSet(unsupportedOptions);
+        ADDITIONAL_OPTIONS = new Options();
+    }
+    /**
+     * Create an Instance.
+     */
+    public MavenOptionCollection() {
+        super(UNSUPPORTED_OPTIONS, new 
Options().addOptions(ADDITIONAL_OPTIONS));
+        defaultOverride = new HashMap<>();
+    }
+
+    static String rename(final String name) {
+        return StringUtils.defaultIfEmpty(RENAME_MAP.get(name), name);
+    }
+
+    CasedString createName(final Option option) {
+        List<String> pluralEndings = List.of("approved", "denied");
+        String name = rename(ArgumentTracker.extractKey(option));
+        CasedString casedName = new CasedString(CasedString.StringCase.KEBAB, 
name);
+        String[] segments = casedName.getSegments();
+        String lastSegment = segments[segments.length - 1];
+        if (option.hasArgs()) {
+            if (!lastSegment.endsWith("s") && 
!pluralEndings.contains(lastSegment)) {
+                segments[segments.length - 1] += "s";
+                casedName = new CasedString(CasedString.StringCase.KEBAB, 
segments);
+            }
+        }
+        return casedName.as(CasedString.StringCase.CAMEL);
+    }
+
+    @Override
+    protected Function<Option, MavenOption> getMapper() {
+        return option -> new MavenOption(this, option, createName(option));
+    }
+
+    @Override
+    protected Map<Option, String> defaultOverrides() {
+        return defaultOverride;
+    }
+
+    @Override
+    public void addOverride(final Option option, final String value) {
+        defaultOverride.put(option, value);
+    }
 }
diff --git 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/PropertyReader.java
 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/PropertyReader.java
index 2e3cea96..aa64b5f4 100644
--- 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/PropertyReader.java
+++ 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/PropertyReader.java
@@ -1,4 +1,19 @@
 package org.apache.rat.maven;
 
-public class PropertyReader {
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public final class PropertyReader {
+    private PropertyReader() {
+        // do not instantiate
+    }
+    public static Properties read(final String propertyFileName) throws 
IOException {
+        try (InputStream is = PropertyReader.class.getClassLoader()
+                .getResourceAsStream(propertyFileName)) {
+            Properties properties = new Properties();
+            properties.load(is);
+            return properties;
+        }
+    }
 }
diff --git 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/package-info.java
 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/package-info.java
index 6be482b3..78f53094 100644
--- 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/package-info.java
+++ 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/package-info.java
@@ -17,6 +17,6 @@
  * under the License.
  */
 /**
- * RAT Maven plugin tools.
+ * RAT Maven plugin and tools shared files.
  */
 package org.apache.rat.maven;
diff --git 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/tools/CodeGenerator.java
 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/tools/CodeGenerator.java
index 1f8b957f..4b6beacf 100644
--- 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/tools/CodeGenerator.java
+++ 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/tools/CodeGenerator.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.rat.maven;
+package org.apache.rat.maven.tools;
 
 import java.io.File;
 import java.io.FileWriter;
@@ -25,6 +25,9 @@ import java.io.StringWriter;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
 import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.TreeMap;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.DefaultParser;
@@ -35,16 +38,17 @@ import org.apache.commons.cli.ParseException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.text.WordUtils;
 import org.apache.rat.DeprecationReporter;
-import org.apache.rat.testhelpers.FileUtils;
-import org.apache.rat.ui.OptionFactory;
+import org.apache.rat.OptionCollectionParser;
+import org.apache.rat.maven.MavenOption;
+import org.apache.rat.maven.MavenOptionCollection;
 import org.apache.rat.utils.CasedString;
+import org.apache.rat.utils.FileUtils;
 import org.apache.velocity.Template;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 import org.apache.velocity.runtime.RuntimeConstants;
 
 import static java.lang.String.format;
-import static org.apache.rat.OptionCollection.ArgumentType.NONE;
 
 /**
  * Generates the ${code org.apache.rat.maven.AbstractMaven} source code.
@@ -54,6 +58,8 @@ public final class CodeGenerator {
     private static final String SYNTAX = String.format("java -cp ... %s 
[options]", CodeGenerator.class.getName());
     /** The package name for this AbstractMaven file */
     private final CasedString packageName = new 
CasedString(CasedString.StringCase.DOT, "org.apache.rat.maven");
+    /** The maven option collection */
+    private final MavenOptionCollection mavenOptionCollection = new 
MavenOptionCollection();
     /** The base source directory */
     private final String baseDirectory;
     /** The template for the methods within {@code AbstractMaven}. */
@@ -65,7 +71,7 @@ public final class CodeGenerator {
      * private constructor.
      * @param baseDirectory The base source directory.
      */
-    private CodeGenerator(final String baseDirectory) {
+    CodeGenerator(final String baseDirectory) {
         this.baseDirectory = baseDirectory;
 
         final VelocityEngine velocityEngine = new VelocityEngine();
@@ -120,9 +126,9 @@ public final class CodeGenerator {
      * @throws IOException on IO error
      */
     private void execute() throws IOException {
-        final String methods = gatherMethods();
+        final Map<MavenOption, String> methods = gatherMethods();
         final VelocityContext context = new VelocityContext();
-        context.put("methods", methods);
+        context.put("methods", String.join("\n\n", methods.values()));
         File javaFile = 
Path.of(baseDirectory).resolve(packageName.toCase(CasedString.StringCase.SLASH))
                 .resolve("AbstractMaven.java").toFile();
         FileUtils.mkDir(javaFile.getParentFile());
@@ -139,12 +145,16 @@ public final class CodeGenerator {
     private String createDesc(final MavenOption mavenOption) {
         String desc = mavenOption.getDescription();
         if (desc == null) {
-            throw new IllegalStateException(format("Description for %s may not 
be null", mavenOption.getName()));
-        }
-        if (!desc.contains(".")) {
-            throw new IllegalStateException(format("First sentence of 
description for %s must end with a '.'", mavenOption.getName()));
+            if (!mavenOption.isDeprecated()) {
+                throw new IllegalStateException(format("Description for %s may 
not be null", mavenOption.getName()));
+            }
+            desc = "";
+        } else {
+            if (!desc.contains(".")) {
+                throw new IllegalStateException(format("First sentence of 
description for %s must end with a '.'", mavenOption.getName()));
+            }
         }
-        if (mavenOption.getArgType() != NONE) {
+        if (mavenOption.getArgType() != 
OptionCollectionParser.ArgumentType.NONE) {
             desc = format("%s Argument%s should be %s%s. (See Argument Types 
for clarification)", desc, mavenOption.hasArgs() ? "s" : "",
                     mavenOption.hasArgs() ? "" : "a ", 
mavenOption.getArgName());
         }
@@ -166,16 +176,16 @@ public final class CodeGenerator {
         }
     }
 
-    /**
-     * Gets method name for the method in {@code AbstractMaven.java}.
-     * @param mavenOption the maven option generating the method.
-     * @return the method name description for the method in {@code 
AbstractMaven.java}.
-     */
-    private String createMethodName(final MavenOption mavenOption) {
-        String fname = WordUtils.capitalize(mavenOption.getName());
-        return (mavenOption.hasArgs() && !(fname.endsWith("s") || 
fname.endsWith("Approved") || fname.endsWith("Denied"))) ?
-                fname + "s" : fname;
-    }
+//    /**
+//     * Gets method name for the method in {@code AbstractMaven.java}.
+//     * @param mavenOption the maven option generating the method.
+//     * @return the method name description for the method in {@code 
AbstractMaven.java}.
+//     */
+//    private String createMethodName(final MavenOption mavenOption) {
+//        String fname = mavenOption.getMethodName();
+//        return (mavenOption.hasArgs() && !(fname.endsWith("s") || 
fname.endsWith("Approved") || fname.endsWith("Denied"))) ?
+//                fname + "s" : fname;
+//    }
 
     /**
      * Gets parameter annotation for the method in {@code AbstractMaven.java}.
@@ -204,21 +214,22 @@ public final class CodeGenerator {
      * Gathers all method definitions into a single string.
      * @return the definition of all the methods.
      */
-    private String gatherMethods() {
+    Map<MavenOption, String> gatherMethods() {
+        final Map<MavenOption, String> methods = new 
TreeMap<>(Comparator.comparing(MavenOption::getName));
         final VelocityContext context = new VelocityContext();
-        final StringWriter methodWriter = new StringWriter();
-        for (MavenOption mavenOption : 
OptionFactory.getOptions(MavenOption.FACTORY_CONFIG).toList()) {
+        mavenOptionCollection.getMappedOptions().forEach(mavenOption -> {
+            final StringWriter methodWriter = new StringWriter();
             context.put("option", mavenOption);
             String desc = createDesc(mavenOption);
             context.put("desc", desc);
             context.put("argDesc", createArgDesc(mavenOption, desc));
-            String functionName = createMethodName(mavenOption);
-            context.put("fname", functionName);
+            context.put("fname", mavenOption.getMethodName());
             context.put("parameterAnnotation", 
createParameterAnnotation(mavenOption, mavenOption.getName()));
             context.put("args", (mavenOption.hasArg() ? "String" : "boolean") 
+ (mavenOption.hasArgs() ? "[]" : ""));
-
             methodTemplate.merge(context, methodWriter);
-        }
-        return methodWriter.toString();
+
+            methods.put(mavenOption, methodWriter.toString());
+        });
+        return methods;
     }
 }
diff --git 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/tools/TestGenerator.java
 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/tools/TestGenerator.java
index 41df233e..400eaa4f 100644
--- 
a/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/tools/TestGenerator.java
+++ 
b/apache-rat-maven-parent/tools/src/main/java/org/apache/rat/maven/tools/TestGenerator.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.rat.maven;
+package org.apache.rat.maven.tools;
 
 import java.io.File;
 import java.io.FileWriter;
@@ -27,6 +27,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.Locale;
+import java.util.Properties;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.DefaultParser;
@@ -35,13 +36,15 @@ import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.commons.text.WordUtils;
 import org.apache.rat.DeprecationReporter;
 import org.apache.rat.VersionInfo;
-import org.apache.rat.testhelpers.FileUtils;
+import org.apache.rat.maven.MavenOption;
+import org.apache.rat.maven.MavenOptionCollection;
+import org.apache.rat.maven.PropertyReader;
 import org.apache.rat.testhelpers.data.ReportTestDataProvider;
 import org.apache.rat.testhelpers.data.TestData;
 import org.apache.rat.utils.CasedString;
+import org.apache.rat.utils.FileUtils;
 import org.apache.velocity.Template;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
@@ -56,25 +59,22 @@ public final class TestGenerator {
     /** They syntax for this command */
     private static final String SYNTAX = String.format("java -cp ... %s 
[options]", TestGenerator.class.getName());
     /** The package name as a cased string */
-    private final CasedString packageName;
+    private CasedString packageName;
     /** The resource directory where the test resources will be written */
-    private final Path resourceDirectory;
+    private Path resourceDirectory;
     /** The directory where the test classes will be written*/
-    private final Path testDirectory;
+    private Path testDirectory;
     /** The template for the pom.xml files */
     private final Template pomTemplate;
     /** The template for the test class file */
     private final Template javaTemplate;
     /** The template for the methods within the test class */
     private final Template methodTemplate;
+    /** The Maven properties */
+    private final Properties properties;
 
-
-    @SuppressFBWarnings("PATH_TRAVERSAL_IN")
-    private TestGenerator(final String packageName, final String 
resourceDirectory, final String testDirectory) {
-        this.packageName = new CasedString(CasedString.StringCase.DOT, 
packageName);
-        this.resourceDirectory = Paths.get(resourceDirectory);
-        this.testDirectory = 
Paths.get(testDirectory).resolve(this.packageName.toCase(CasedString.StringCase.SLASH));
-
+    public TestGenerator() throws IOException {
+        properties = PropertyReader.read("app.properties");
         VelocityEngine velocityEngine = new VelocityEngine();
         velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, 
"classpath");
         velocityEngine.setProperty("classpath.resource.loader.class", 
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
@@ -91,6 +91,14 @@ public final class TestGenerator {
         methodTemplate = 
velocityEngine.getTemplate(CasedString.StringCase.SLASH.assemble(nameParts));
     }
 
+    @SuppressFBWarnings("PATH_TRAVERSAL_IN")
+    TestGenerator(final String packageName, final String resourceDirectory, 
final String testDirectory) throws IOException {
+        this();
+        this.packageName = new CasedString(CasedString.StringCase.DOT, 
packageName);
+        this.resourceDirectory = Paths.get(resourceDirectory);
+        this.testDirectory = 
Paths.get(testDirectory).resolve(this.packageName.toCase(CasedString.StringCase.SLASH));
+    }
+
     /**
      * Gets the resource path.
      * @return the resource path.
@@ -146,17 +154,25 @@ public final class TestGenerator {
      * Execute the generation.
      * @throws IOException on IO error.
      */
-    private void execute() throws IOException {
+    void execute() throws IOException {
         VelocityContext context = new VelocityContext();
         context.put("packageName", packageName.toString());
 
         final VersionInfo versionInfo = new VersionInfo(TestGenerator.class);
-        context.put("rat_version", versionInfo.getSpecVersion());
+        context.put("rat_version", ratVersion());
         context.put("plugin_version", versionInfo.getVersion());
         context.put("tests", writeTestPoms(context));
         writeTestFiles(context);
     }
 
+    public String ratVersion() {
+        return properties.getProperty("rat.version");
+    }
+
+    public String pluginVersion() {
+        return properties.getProperty("rat.plugin.version");
+    }
+
     /**
      * Write the {@code MavenTest.java} file
      * @param context The velocity context to write the test file with.
@@ -170,6 +186,26 @@ public final class TestGenerator {
         }
     }
 
+    public String buildPom(final MavenOptionCollection optionCollection, final 
TestData testData) {
+        final VelocityContext context =  new VelocityContext();
+        CasedString casedTestName = new 
CasedString(CasedString.StringCase.CAMEL, testData.getClassName());
+        context.put("artifactId", 
casedTestName.toCase(CasedString.StringCase.KEBAB).toLowerCase(Locale.ROOT));
+        context.put("testName", testData.getTestName());
+        context.put("rat_version", ratVersion());
+        context.put("plugin_version", pluginVersion());
+        StringBuilder configuration = new StringBuilder();
+        for (Pair<Option, String[]> pair : testData.getArgs()) {
+            if (pair.getKey() != null) {
+                MavenOption option = 
optionCollection.getMappedOption(pair.getKey());
+                
configuration.append(option.getExample(pair.getRight())).append(System.lineSeparator());
+            }
+        }
+        context.put("rat_configuration", configuration.toString());
+        StringWriter writer = new StringWriter();
+            pomTemplate.merge(context, writer);
+        return writer.toString();
+    }
+
     /**
      * Write the test poms for all the supported options.
      * Generates method definitions (one for each pom file) to be included in 
{@code MavenTest.java}.
@@ -178,11 +214,12 @@ public final class TestGenerator {
      * @throws IOException on IO error
      */
     private String writeTestPoms(final VelocityContext context) throws 
IOException {
-
+        MavenOptionCollection optionCollection = new MavenOptionCollection();
         StringWriter funcCode = new StringWriter();
 
-        for (final TestData testData : new 
ReportTestDataProvider().getOptionTests(MavenOption.UNSUPPORTED_SET)) {
-            context.put("option", testData.getOption());
+        for (final TestData testData : new 
ReportTestDataProvider().getOptionTests(optionCollection)) {
+            String config = buildPom(optionCollection, testData);
+            //context.put("option", testData.getOption());
             // relative directory to test resources.
             Path testDir = 
Paths.get("src/test/resources").resolve(packageName.toCase(CasedString.StringCase.SLASH))
                     .resolve("stubs").resolve(testData.getTestName());
@@ -194,26 +231,14 @@ public final class TestGenerator {
             Path testPath = resourcePath().resolve(testData.getTestName());
             context.put("baseDir", testPath.toFile().getAbsolutePath());
             FileUtils.mkDir(testPath.toFile());
-            CasedString casedTestName = new 
CasedString(CasedString.StringCase.CAMEL, testData.getClassName());
-            context.put("artifactId", 
casedTestName.toCase(CasedString.StringCase.KEBAB).toLowerCase(Locale.ROOT));
+            //CasedString casedTestName = new 
CasedString(CasedString.StringCase.CAMEL, testData.getClassName());
             context.put("testName", testData.getTestName());
-            context.put("stubName", testData.getClassName());
-            context.put("funcName", 
WordUtils.uncapitalize(testData.getClassName()));
-
-            StringBuilder configuration = new StringBuilder();
-            for (Pair<Option, String[]> pair : testData.getArgs()) {
-                if (pair.getKey() != null) {
-                    MavenOption option = new MavenOption(pair.getKey());
-                    
configuration.append(option.getExample(pair.getRight())).append(System.lineSeparator());
-                }
-            }
-            context.put("rat_configuration", configuration.toString());
+            methodTemplate.merge(context, funcCode);
 
             File pomFile = testPath.resolve("pom.xml").toFile();
             try (FileWriter writer = new FileWriter(pomFile, 
StandardCharsets.UTF_8)) {
-                pomTemplate.merge(context, writer);
+                writer.append(buildPom(optionCollection, testData));
             }
-            methodTemplate.merge(context, funcCode);
         }
         return funcCode.toString();
     }
diff --git 
a/apache-rat-maven-parent/tools/src/main/resources/org/apache/rat/maven/tools/AbstractMaven.vm
 
b/apache-rat-maven-parent/tools/src/main/resources/org/apache/rat/maven/tools/AbstractMaven.vm
index 1f0cad12..b0935c5a 100644
--- 
a/apache-rat-maven-parent/tools/src/main/resources/org/apache/rat/maven/tools/AbstractMaven.vm
+++ 
b/apache-rat-maven-parent/tools/src/main/resources/org/apache/rat/maven/tools/AbstractMaven.vm
@@ -19,15 +19,11 @@
 
 package org.apache.rat.maven;
 
-import java.util.List;
-import java.util.stream.Collectors;
-
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.rat.commandline.Arg;
 import org.apache.rat.config.exclusion.StandardCollection;
 import org.apache.rat.ui.ArgumentTracker;
-import org.apache.rat.ui.OptionFactory;
 
 /**
  * Generated class to provide Maven support for standard RAT command line 
options
@@ -37,10 +33,12 @@ import org.apache.rat.ui.OptionFactory;
 public abstract class AbstractMaven extends AbstractMojo {
     /** The arguments that have been set */
     protected final ArgumentTracker argumentTracker;
+    /** The collection of Maven options */
+    protected final MavenOptionCollection mavenOptionCollection;
 
     protected AbstractMaven() {
-        List<MavenOption> mavenList = 
OptionFactory.getOptions(MavenOption.FACTORY_CONFIG).collect(Collectors.toList());
-        argumentTracker = new ArgumentTracker(mavenList);
+        mavenOptionCollection = new MavenOptionCollection();
+        argumentTracker = new 
ArgumentTracker(mavenOptionCollection.getMappedOptions().toList());
         
argumentTracker.addArg(ArgumentTracker.extractKey(Arg.EXCLUDE_STD.option()), 
StandardCollection.MAVEN.name());
     }
 
diff --git 
a/apache-rat-maven-parent/tools/src/main/resources/org/apache/rat/maven/tools/AbstractMavenFunc.vm
 
b/apache-rat-maven-parent/tools/src/main/resources/org/apache/rat/maven/tools/AbstractMavenFunc.vm
index 0ff12218..a3c20f6c 100644
--- 
a/apache-rat-maven-parent/tools/src/main/resources/org/apache/rat/maven/tools/AbstractMavenFunc.vm
+++ 
b/apache-rat-maven-parent/tools/src/main/resources/org/apache/rat/maven/tools/AbstractMavenFunc.vm
@@ -17,7 +17,9 @@
  * under the License.
  *#
     /**
+#if (${desc} != "")
      * ${desc}
+#end
      * @param ${option.getName} ${argDesc}
 #if (${option.isDeprecated})
      * @deprecated ${option.getDeprecated}
@@ -27,7 +29,7 @@
     @Deprecated
 #end
     ${parameterAnnotation}
-    public void set${fname}(final ${args} ${option.getName}) {
+    public void ${fname}(final ${args} ${option.getName}) {
 #if (${option.hasArg})
   #if (${option.hasArgs})
         argumentTracker.addArg("${option.keyValue}", ${option.getName});
diff --git 
a/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/MavenOptionCollectionTest.java
 
b/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/MavenOptionCollectionTest.java
index 3eaf0667..5bad43ec 100644
--- 
a/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/MavenOptionCollectionTest.java
+++ 
b/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/MavenOptionCollectionTest.java
@@ -1,17 +1,23 @@
 package org.apache.rat.maven;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
+import java.util.stream.Stream;
 import org.apache.commons.cli.DeprecatedAttributes;
 import org.apache.commons.cli.Option;
 import org.apache.rat.commandline.Arg;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-public class MavenOptionTest {
+public class MavenOptionCollectionTest {
 
     @Test
-    void deprecatedTest() {
+    void deprecatedOptionTest() {
         final MavenOptionCollection  mavenOptionCollection = new 
MavenOptionCollection();
         MavenOption opt = 
mavenOptionCollection.getMappedOption(Arg.EDIT_COPYRIGHT.find("copyright"));
 
@@ -47,6 +53,45 @@ public class MavenOptionTest {
         } finally {
             assertThat(new 
MavenOptionCollection().additionalOptions().getOptions()).isEmpty();
         }
+    }
+
+    @ParameterizedTest
+    @MethodSource("namingTestData")
+    public void namingTest(String expectedName, Option option) {
+        MavenOptionCollection collection = new MavenOptionCollection();
+        MavenOption mavenOption = collection.getMappedOption(option);
+        assertThat(mavenOption.getName()).isEqualTo(expectedName);
+    }
+
+    static Stream<Arguments> namingTestData() {
+        List<Arguments> lst  = new ArrayList<>();
+        Option option = 
Option.builder().longOpt("multiple-args").hasArgs().build();
+        lst.add(Arguments.of("multipleArgs", option));
+        option = 
Option.builder().longOpt("multiple-arg-single-name").hasArgs().build();
+        lst.add(Arguments.of("multipleArgSingleNames", option));
+        option = 
Option.builder().longOpt("multiple-args-approved").hasArgs().build();
+        lst.add(Arguments.of("multipleArgsApproved", option));
+        option = 
Option.builder().longOpt("multiple-args-denied").hasArgs().build();
+        lst.add(Arguments.of("multipleArgsDenied", option));
+
+        option = Option.builder().longOpt("single-args").hasArg().build();
+        lst.add(Arguments.of("singleArgs", option));
+        option = 
Option.builder().longOpt("single-arg-single-name").hasArg().build();
+        lst.add(Arguments.of("singleArgSingleName", option));
+        option = 
Option.builder().longOpt("single-arg-approved").hasArg().build();
+        lst.add(Arguments.of("singleArgApproved", option));
+        option = 
Option.builder().longOpt("single-args-denied").hasArg().build();
+        lst.add(Arguments.of("singleArgsDenied", option));
+
+        option = Option.builder().longOpt("no-args").build();
+        lst.add(Arguments.of("noArgs", option));
+        option = Option.builder().longOpt("no-arg-single-name").build();
+        lst.add(Arguments.of("noArgSingleName", option));
+        option = Option.builder().longOpt("no-args-approved").build();
+        lst.add(Arguments.of("noArgsApproved", option));
+        option = Option.builder().longOpt("no-args-denied").build();
+        lst.add(Arguments.of("noArgsDenied", option));
 
+        return lst.stream();
     }
 }
diff --git 
a/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/PropertyReaderTest.java
 
b/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/PropertyReaderTest.java
index fc7f65dd..f1827230 100644
--- 
a/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/PropertyReaderTest.java
+++ 
b/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/PropertyReaderTest.java
@@ -1,4 +1,17 @@
 package org.apache.rat.maven;
 
+import java.io.IOException;
+import java.util.Properties;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
 public class PropertyReaderTest {
+    @Test
+    public void testReadProperties() throws IOException {
+        Properties properties = PropertyReader.read("app.properties");
+        assertThat(properties).isNotEmpty();
+        assertThat(properties.getProperty("rat.version")).isNotEmpty();
+        assertThat(properties.getProperty("rat.plugin.version")).isNotEmpty();
+    }
 }
diff --git 
a/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/tools/CodeGeneratorTest.java
 
b/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/tools/CodeGeneratorTest.java
index 980049f9..93132026 100644
--- 
a/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/tools/CodeGeneratorTest.java
+++ 
b/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/tools/CodeGeneratorTest.java
@@ -1,4 +1,38 @@
 package org.apache.rat.maven.tools;
 
+import java.nio.file.Path;
+import java.util.Map;
+import org.apache.rat.commandline.Arg;
+import org.apache.rat.maven.MavenOption;
+import org.apache.rat.maven.MavenOptionCollection;
+import org.apache.rat.testhelpers.TextUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
 public class CodeGeneratorTest {
+    @TempDir
+    private Path testPath;
+    private CodeGenerator codeGenerator;
+
+    CodeGeneratorTest() {}
+
+    @BeforeEach
+    void setup() {
+        codeGenerator = new CodeGenerator(testPath.toString());
+    }
+
+    @Test
+    public void testGenerateMethods() throws Exception {
+        MavenOptionCollection mavenOptionCollection = new 
MavenOptionCollection();
+        Map<MavenOption, String> methods = codeGenerator.gatherMethods();
+        MavenOption mavenOption = 
mavenOptionCollection.getMappedOption(Arg.EXCLUDE.option());
+        String methodText = methods.get(mavenOption);
+        TextUtils.assertContains("public void setInputExcludes(final String[] 
inputExcludes) {", methodText);
+
+        mavenOption = 
mavenOptionCollection.getMappedOption(Arg.FAMILIES_APPROVED.option());
+        methodText = methods.get(mavenOption);
+        TextUtils.assertContains("public void setLicenseFamiliesApproved(final 
String licenseFamiliesApproved) {", methodText);
+        TextUtils.assertContainsExactly(1, "public void set", methodText);
+    }
 }
diff --git 
a/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/tools/TestGeneratorTest.java
 
b/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/tools/TestGeneratorTest.java
index bb3dae66..0f6fef57 100644
--- 
a/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/tools/TestGeneratorTest.java
+++ 
b/apache-rat-maven-parent/tools/src/test/java/org/apache/rat/maven/tools/TestGeneratorTest.java
@@ -1,4 +1,52 @@
 package org.apache.rat.maven.tools;
 
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.cli.Option;
+import org.apache.rat.commandline.Arg;
+import org.apache.rat.maven.MavenOption;
+import org.apache.rat.maven.MavenOptionCollection;
+import org.apache.rat.testhelpers.TextUtils;
+import org.apache.rat.testhelpers.data.ReportTestDataProvider;
+import org.apache.rat.testhelpers.data.TestData;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
 public class TestGeneratorTest {
+
+    @TempDir
+    private Path testPath;
+    private TestGenerator testGenerator;
+    private MavenOptionCollection optionCollection = new  
MavenOptionCollection();
+    TestGeneratorTest() {}
+
+    @BeforeEach
+    void setup() throws IOException {
+        testGenerator = new TestGenerator("package.name", 
testPath.resolve("resources").toString(), 
testPath.resolve("source").toString());
+    }
+
+    private List<TestData> testsFor(Option option) {
+        Set<TestData> testDataList = new 
ReportTestDataProvider().getOptionTests(optionCollection);
+        return testDataList.stream().filter(td -> td.getOption() == null ? 
option == null : td.getOption().equals(option)).toList();
+    }
+
+    @ParameterizedTest
+    @MethodSource("optionsSource")
+    void test(MavenOption mavenOption) throws IOException {
+        List<TestData> testDataList = testsFor(mavenOption.getOption());
+        for (final TestData testData : testDataList) {
+            String pomText = testGenerator.buildPom(optionCollection, 
testData);
+            TextUtils.assertContains("<" + mavenOption.getName(), pomText);
+        }
+    }
+
+    static List<MavenOption> optionsSource() {
+        return new MavenOptionCollection().getMappedOptions().toList();
+    }
 }

Reply via email to