From d1309cb1ad94d324193b39aaffdc03512bd5e763 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Sun, 22 Mar 2026 08:21:54 +0000
Subject: [PATCH 01/11] initial working code
---
apache-rat-core/pom.xml | 25 +-
.../main/java/org/apache/rat/CLIOption.java | 73 ++
.../org/apache/rat/CLIOptionCollection.java | 41 +
.../java/org/apache/rat/OptionCollection.java | 12 +-
.../apache/rat/OptionCollectionParser.java | 325 ++++++++
.../java/org/apache/rat/commandline/Arg.java | 703 +++++++++---------
.../rat/commandline/ArgumentContext.java | 7 +-
.../org/apache/rat/help/AbstractHelp.java | 5 +-
.../apache/rat/ui/AbstractCodeGenerator.java | 151 ++++
.../org/apache/rat/ui/ArgumentTracker.java | 239 ++++++
.../src/main/java/org/apache/rat/ui/UI.java | 36 +
.../main/java/org/apache/rat/ui/UIOption.java | 224 ++++++
.../org/apache/rat/ui/UIOptionCollection.java | 299 ++++++++
.../apache/rat/ui/UpdatableOptionGroup.java | 85 +++
.../ui/UpdatableOptionGroupCollection.java | 110 +++
.../java/org/apache/rat/ui/package-info.java | 23 +
.../org/apache/rat/ui/spi/UIProvider.java | 25 +
.../org/apache/rat/ui/spi/package-info.java | 22 +
.../org/apache/rat/commandline/ArgTests.java | 3 +-
.../apache/rat/ui/ArgumentTrackerTest.java | 122 +++
.../apache/rat/ui/UIOptionCollectionTest.java | 160 ++++
.../rat/documentation/options/CLIOption.java | 2 +-
pom.xml | 10 +
23 files changed, 2312 insertions(+), 390 deletions(-)
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/CLIOption.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/CLIOptionCollection.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/OptionCollectionParser.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/AbstractCodeGenerator.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/ArgumentTracker.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/UI.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/UIOption.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/UIOptionCollection.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/UpdatableOptionGroup.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/UpdatableOptionGroupCollection.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/package-info.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/spi/UIProvider.java
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/ui/spi/package-info.java
create mode 100644 apache-rat-core/src/test/java/org/apache/rat/ui/ArgumentTrackerTest.java
create mode 100644 apache-rat-core/src/test/java/org/apache/rat/ui/UIOptionCollectionTest.java
diff --git a/apache-rat-core/pom.xml b/apache-rat-core/pom.xml
index 3984e84a9..a4c35b8c2 100644
--- a/apache-rat-core/pom.xml
+++ b/apache-rat-core/pom.xml
@@ -37,7 +37,6 @@
src/main/filtered-resources
- org.apache.rat
@@ -56,9 +55,6 @@
-
-
- org.apache.maven.pluginsmaven-jar-plugin
@@ -177,8 +173,20 @@
- org.apache.rat
- apache-rat-testdata
+ com.github.spotbugs
+ spotbugs-annotations
+
+
+ org.apache.velocity
+ velocity-engine-core
+
+
+ org.apache.velocity.tools
+ velocity-tools-generic
+
+
+ org.reflections
+ reflectionstest
@@ -213,11 +221,6 @@
junit-jupiter-apitest
-
- org.junit.vintage
- junit-vintage-engine
- test
- org.junit.jupiterjunit-jupiter-params
diff --git a/apache-rat-core/src/main/java/org/apache/rat/CLIOption.java b/apache-rat-core/src/main/java/org/apache/rat/CLIOption.java
new file mode 100644
index 000000000..03b790440
--- /dev/null
+++ b/apache-rat-core/src/main/java/org/apache/rat/CLIOption.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import org.apache.commons.cli.Option;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rat.ui.ArgumentTracker;
+import org.apache.rat.ui.UIOption;
+import org.apache.rat.ui.UIOptionCollection;
+
+/**
+ * The CLI option definition.
+ */
+public final class CLIOption extends UIOption {
+
+ public CLIOption(final UIOptionCollection collection, final Option option) {
+ super(collection, option, ArgumentTracker.extractKey(option));
+ }
+
+ @Override
+ public String getText() {
+ StringBuilder result = new StringBuilder();
+ if (option.getLongOpt() != null) {
+ result.append("--").append(option.getLongOpt());
+ if (option.getOpt() != null) {
+ result.append(" or -").append(option.getArgs());
+ }
+ } else {
+ result.append("-").append(option.getArgs());
+ }
+ return result.toString();
+ }
+
+ @Override
+ protected String cleanupName(final Option option) {
+ return ArgumentTracker.extractKey(option);
+ }
+
+ @Override
+ public String getExample() {
+ StringBuilder sb = new StringBuilder("-");
+ if (option.getLongOpt() != null) {
+ sb.append("-").append(option.getLongOpt());
+ } else {
+ sb.append(option.getOpt());
+ }
+ if (option.hasArg()) {
+ String argName = StringUtils.defaultIfBlank(option.getArgName(), "Arg");
+ sb.append(" ").append(argName);
+ if (option.hasArgs()) {
+ sb.append(" [").append(argName).append("2 [").append(argName)
+ .append("3 [...]]] --");
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/CLIOptionCollection.java b/apache-rat-core/src/main/java/org/apache/rat/CLIOptionCollection.java
new file mode 100644
index 000000000..feb1cbf51
--- /dev/null
+++ b/apache-rat-core/src/main/java/org/apache/rat/CLIOptionCollection.java
@@ -0,0 +1,41 @@
+/*
+ * 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
+ *
+ * https://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;
+
+import org.apache.commons.cli.Option;
+import org.apache.rat.ui.UIOptionCollection;
+
+public final class CLIOptionCollection extends UIOptionCollection {
+ /** The Help option */
+ static final Option HELP = new Option("?", "help", false, "Print help for the RAT command line interface and exit.");
+
+ /** The instance of the collection */
+ public static final CLIOptionCollection INSTANCE = new CLIOptionCollection();
+
+ private CLIOptionCollection() {
+ super(new Builder().uiOption(HELP)
+ .mapper(CLIOption::new));
+ }
+
+ private static final class Builder extends UIOptionCollection.Builder {
+ private Builder() {
+ super();
+ }
+ }
+}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java b/apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java
index 6ce2e1c2d..b16ebd092 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java
@@ -140,9 +140,8 @@ public static ReportConfiguration parseCommands(final File workingDirectory, fin
// for "commandLine"
}
- Arg.processLogLevel(commandLine);
-
ArgumentContext argumentContext = new ArgumentContext(workingDirectory, commandLine);
+ Arg.processLogLevel(argumentContext, CLIOptionCollection.INSTANCE);
if (commandLine.hasOption(HELP)) {
helpCmd.accept(opts);
@@ -175,14 +174,15 @@ public static ReportConfiguration parseCommands(final File workingDirectory, fin
* @see #parseCommands(File, String[], Consumer, boolean)
*/
static ReportConfiguration createConfiguration(final ArgumentContext argumentContext) {
- argumentContext.processArgs();
+ argumentContext.processArgs(CLIOptionCollection.INSTANCE);
final ReportConfiguration configuration = argumentContext.getConfiguration();
final CommandLine commandLine = argumentContext.getCommandLine();
- if (Arg.DIR.isSelected()) {
+ if (CLIOptionCollection.INSTANCE.isSelected(Arg.DIR)) {
try {
- configuration.addSource(getReportable(commandLine.getParsedOptionValue(Arg.DIR.getSelected()), configuration));
+ configuration.addSource(getReportable(commandLine.getParsedOptionValue(
+ CLIOptionCollection.INSTANCE.getSelected(Arg.DIR).get()), configuration));
} catch (ParseException e) {
- throw new ConfigurationException("Unable to set parse " + Arg.DIR.getSelected(), e);
+ throw new ConfigurationException("Unable to set parse " + CLIOptionCollection.INSTANCE.getSelected(Arg.DIR).get(), e);
}
}
for (String s : commandLine.getArgs()) {
diff --git a/apache-rat-core/src/main/java/org/apache/rat/OptionCollectionParser.java b/apache-rat-core/src/main/java/org/apache/rat/OptionCollectionParser.java
new file mode 100644
index 000000000..5798b7385
--- /dev/null
+++ b/apache-rat-core/src/main/java/org/apache/rat/OptionCollectionParser.java
@@ -0,0 +1,325 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Serial;
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+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.rat.api.Document;
+import org.apache.rat.commandline.Arg;
+import org.apache.rat.commandline.ArgumentContext;
+import org.apache.rat.commandline.StyleSheets;
+import org.apache.rat.config.exclusion.StandardCollection;
+import org.apache.rat.document.DocumentName;
+import org.apache.rat.document.DocumentNameMatcher;
+import org.apache.rat.document.FileDocument;
+import org.apache.rat.help.Licenses;
+import org.apache.rat.license.LicenseSetFactory;
+import org.apache.rat.report.IReportable;
+import org.apache.rat.report.claim.ClaimStatistic;
+import org.apache.rat.ui.UIOptionCollection;
+import org.apache.rat.utils.DefaultLog;
+import org.apache.rat.utils.Log.Level;
+import org.apache.rat.walker.ArchiveWalker;
+import org.apache.rat.walker.DirectoryWalker;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+import static java.lang.String.format;
+
+/**
+ * Uses the AbstractOptionCollection to parse the command line options.
+ * contains utility methods to ReportConfiguration from the options and an array of arguments.
+ */
+@SuppressFBWarnings("EI_EXPOSE_REP2")
+public final class OptionCollectionParser {
+ /** The OptionCollection that we are working with */
+ private final UIOptionCollection> uiOptionCollection;
+
+ public OptionCollectionParser(final UIOptionCollection> optionCollection) {
+ this.uiOptionCollection = optionCollection;
+ }
+
+ /** The Option comparator to sort the help */
+ public static final Comparator
findDeprecatedOption() {
@Test
void getMappedOption() {
- TestingUIOption one = underTest.getMappedOption(UI_OPTION);
+ TestingUIOption one = underTest.getMappedOption(UI_OPTION).get();
assertThat(one.option).isEqualTo(UI_OPTION);
- assertThat(one.name).isEqualTo("ui.option1");
+ assertThat(one.getName()).isEqualTo("ui.option1");
assertThat(one.isDeprecated()).isFalse();
- TestingUIOption two = underTest.getMappedOption(DEPRECATED_UI_OPTION);
+ TestingUIOption two = underTest.getMappedOption(DEPRECATED_UI_OPTION).get();
assertThat(two.option).isEqualTo(DEPRECATED_UI_OPTION);
- assertThat(two.name).isEqualTo("ui.option2");
+ assertThat(two.getName()).isEqualTo("ui.option2");
assertThat(two.isDeprecated()).isTrue();
- assertThat(underTest.getMappedOption(Arg.EXCLUDE.option())).isNull();
+ assertThat(underTest.getMappedOption(Arg.EXCLUDE.option())).isEmpty();
for (Option option : Arg.COUNTER_MAX.group().getOptions()) {
- assertThat(underTest.getMappedOption(option)).isNull();
+ assertThat(underTest.getMappedOption(option)).isEmpty();
}
- TestingUIOption config = underTest.getMappedOption(Arg.CONFIGURATION.option());
- assertThat(config).isNotNull();
+ Optional optConfig = underTest.getMappedOption(Arg.CONFIGURATION.option());
+ assertThat(optConfig).isPresent();
+ TestingUIOption config = optConfig.get();
assertThat(config.option).isEqualTo(Arg.CONFIGURATION.option());
- assertThat(config.name).isEqualTo("config");
+ assertThat(config.getName()).isEqualTo("config");
- config = underTest.getMappedOption(Option.builder("foo").build());
- assertThat(config).isNull();
+ optConfig = underTest.getMappedOption(Option.builder("foo").build());
+ assertThat(optConfig).isEmpty();
}
@Test
diff --git a/apache-rat-plugin/src/it/RAT-469-default/pom.xml b/apache-rat-plugin/src/it/RAT-469-default/pom.xml
index a962f9da1..9d2ac973c 100644
--- a/apache-rat-plugin/src/it/RAT-469-default/pom.xml
+++ b/apache-rat-plugin/src/it/RAT-469-default/pom.xml
@@ -31,15 +31,11 @@
truetruefalse
-
- pom.xml
-
-
- STANDARD_PATTERNS
- STANDARD_SCMS
- MAVEN
- IDEA
-
+ pom.xml>
+ STANDARD_PATTERNS
+ STANDARD_SCMS
+ MAVEN
+ IDEA
diff --git a/apache-rat-plugin/src/it/RAT-469/pom.xml b/apache-rat-plugin/src/it/RAT-469/pom.xml
index 10ea7967d..19687a2d9 100644
--- a/apache-rat-plugin/src/it/RAT-469/pom.xml
+++ b/apache-rat-plugin/src/it/RAT-469/pom.xml
@@ -32,15 +32,11 @@
GPL3truefalse
-
- pom.xml
-
-
- STANDARD_PATTERNS
- STANDARD_SCMS
- MAVEN
- IDEA
-
+ pom.xml
+ STANDARD_PATTERNS
+ STANDARD_SCMS
+ MAVEN
+ IDEA
diff --git a/apache-rat-plugin/src/it/RAT-508/pom.xml b/apache-rat-plugin/src/it/RAT-508/pom.xml
index 6a66121c6..d0741e00b 100644
--- a/apache-rat-plugin/src/it/RAT-508/pom.xml
+++ b/apache-rat-plugin/src/it/RAT-508/pom.xml
@@ -34,12 +34,8 @@
truetruefalse
-
- pom.xml
-
-
- ALL
-
+ pom.xml
+ ALL
diff --git a/apache-rat-plugin/src/it/RAT-524/invoker.properties b/apache-rat-plugin/src/it/RAT-524/invoker.properties
index 1c089b469..0a419ea70 100644
--- a/apache-rat-plugin/src/it/RAT-524/invoker.properties
+++ b/apache-rat-plugin/src/it/RAT-524/invoker.properties
@@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-invoker.goals = clean -X apache-rat:rat
+invoker.goals = -X clean apache-rat:rat
diff --git a/apache-rat-plugin/src/test/java/org/apache/rat/mp/OptionMojoTest.java b/apache-rat-plugin/src/test/java/org/apache/rat/mp/OptionMojoTest.java
index 7b9e27e41..5268e7048 100644
--- a/apache-rat-plugin/src/test/java/org/apache/rat/mp/OptionMojoTest.java
+++ b/apache-rat-plugin/src/test/java/org/apache/rat/mp/OptionMojoTest.java
@@ -34,6 +34,7 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.io.CleanupMode;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
@@ -52,7 +53,7 @@
import static java.lang.String.format;
import static org.junit.jupiter.api.Assertions.fail;
-
+@Disabled("Change in Maven requires rework")
public class OptionMojoTest {
@TempDir(cleanup = CleanupMode.NEVER)
@@ -133,11 +134,6 @@ protected final ReportConfiguration generateConfig(List>
throw new IOException(e.getMessage(), e);
}
}
-
- @Override
- protected void helpTest() {
- fail("Should not call help");
- }
}
public abstract static class SimpleMojoTestcase extends BetterAbstractMojoTestCase {
diff --git a/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatCheckMojoTest.java b/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatCheckMojoTest.java
index 1afb32eb3..686f4ca1f 100644
--- a/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatCheckMojoTest.java
+++ b/apache-rat-plugin/src/test/java/org/apache/rat/mp/RatCheckMojoTest.java
@@ -463,11 +463,8 @@ void rat107() throws Exception {
final String[] expected = {};
final String[] notExpected = {};
//setVariableValueToObject(mojo, "excludeSubProjects", Boolean.FALSE);
- mojo.setInputExcludeParsedScm("MAVEN");
- mojo.setInputExcludeParsedScm("idea");
- mojo.setInputExcludeParsedScm("eclipse");
+ mojo.setInputExcludeParsedScms(new String[] {"MAVEN", "idea", "eclipse"});
mojo.execute();
-
ensureRatReportIsCorrect(ratTxtFile, expected, notExpected);
}
}
diff --git a/apache-rat-plugin/src/test/resources/unit/it5/pom.xml b/apache-rat-plugin/src/test/resources/unit/it5/pom.xml
index 474872128..4c770efa7 100644
--- a/apache-rat-plugin/src/test/resources/unit/it5/pom.xml
+++ b/apache-rat-plugin/src/test/resources/unit/it5/pom.xml
@@ -28,12 +28,12 @@
@pom.version@xml
- .rat/customConfig.xml
-
- .rat/**
- pom.xml
- invoker.properties
-
+
+ .rat/customConfig.xml
+
+ .rat/**
+ pom.xml
+ invoker.properties
diff --git a/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Help.java b/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Help.java
index 7c6256a17..3f42ed407 100644
--- a/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Help.java
+++ b/apache-rat-tasks/src/main/java/org/apache/rat/anttasks/Help.java
@@ -27,12 +27,14 @@
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
+import org.apache.commons.collections4.list.TreeList;
import org.apache.commons.lang3.StringUtils;
import org.apache.rat.commandline.Arg;
import org.apache.rat.config.exclusion.StandardCollection;
+import org.apache.rat.documentation.options.AntOptionCollection;
import org.apache.rat.help.AbstractHelp;
-import org.apache.rat.documentation.options.AbstractOption;
import org.apache.rat.documentation.options.AntOption;
+import org.apache.rat.ui.UIOption;
import org.apache.rat.utils.DefaultLog;
import org.apache.rat.utils.Log;
@@ -178,11 +180,9 @@ protected StringBuffer renderOptions(final StringBuffer sb, final int width, fin
String descriptionTitle = " -- Description --";
int max = optionTitle.length();
int maxExample = exampleTitle.length();
- final List optList = options.getOptions().stream().filter(Option::hasLongOpt)
- .map(AntOption::new).collect(Collectors.toList());
- if (getOptionComparator() != null) {
- optList.sort(Comparator.comparing(AbstractOption::getName));
- }
+ final List optList = new ArrayList<>();
+ AntOptionCollection.INSTANCE.getMappedOptions().forEach(optList::add);
+ optList.sort(Comparator.comparing(UIOption::getName));
List exampleList = new ArrayList<>();
for (final AntOption option : optList) {
String argName = StringUtils.defaultIfEmpty(option.getArgName(), "value");
diff --git a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/GeneratedReportTest.java b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/GeneratedReportTest.java
index ca86ee4e7..0e39d2f03 100644
--- a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/GeneratedReportTest.java
+++ b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/GeneratedReportTest.java
@@ -30,14 +30,19 @@
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
+
+import org.apache.commons.cli.Option;
import org.apache.commons.lang3.StringUtils;
import org.apache.rat.OptionCollection;
import org.apache.rat.ReportConfiguration;
import org.apache.rat.commandline.Arg;
import org.apache.rat.commandline.StyleSheets;
import org.apache.rat.document.DocumentName;
+import org.apache.rat.documentation.options.AntOptionCollection;
import org.apache.rat.license.LicenseSetFactory;
import org.apache.rat.documentation.options.AntOption;
+import org.apache.rat.ui.ArgumentTracker;
+import org.apache.rat.utils.CasedString;
import org.apache.rat.utils.DefaultLog;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildListener;
@@ -53,62 +58,64 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
+import javax.sound.midi.Track;
+
import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
-public class GeneratedReportTest {
+public class GeneratedReportTest {
@TempDir
static Path tempDir;
private static final Map REQUIRED_ATTRIBUTES = new HashMap<>();
private static final Map REQUIRED_ELEMENTS = new HashMap<>();
- private static final Map ARG_TYPE_MAP = new HashMap<>();
-
- static {
- BuildType buildType = null;
- for (OptionCollection.ArgumentType argType : OptionCollection.ArgumentType.values()) {
- switch (argType) {
- case FILE:
- case DIRORARCHIVE:
- buildType = new BuildType("") {
- @Override
- protected String getMethodFormat(final AntOption antOption) {
- return "";
- }
- };
- break;
- case NONE:
- buildType = new BuildType("") {
- @Override
- protected String getMethodFormat(final AntOption antOption) {
- return "";
- }
- };
- break;
- case STANDARDCOLLECTION:
- buildType = new BuildType("std");
- break;
- case EXPRESSION:
- buildType = new BuildType("expr");
- break;
- case COUNTERPATTERN:
- buildType = new BuildType("cntr");
- break;
- case LICENSEID:
- case FAMILYID:
- buildType = new BuildType("lst");
- break;
- default:
- buildType = new BuildType("") {
- @Override
- protected String getMethodFormat(final AntOption antOption) {
- return format("<%1$s>%%s%1$s>", tag);
- }
- };
- }
- ARG_TYPE_MAP.put(argType, buildType);
- }
- }
+
+
+// static {
+// BuildType buildType = null;
+// for (OptionCollection.ArgumentType argType : OptionCollection.ArgumentType.values()) {
+// switch (argType) {
+// case FILE:
+// case DIRORARCHIVE:
+// buildType = new BuildType("") {
+// @Override
+// protected String getMethodFormat(final AntOption antOption) {
+// return "";
+// }
+// };
+// break;
+// case NONE:
+// buildType = new BuildType("") {
+// @Override
+// protected String getMethodFormat(final AntOption antOption) {
+// return "";
+// }
+// };
+// break;
+// case STANDARDCOLLECTION:
+// buildType = new BuildType("std");
+// break;
+// case EXPRESSION:
+// buildType = new BuildType("expr");
+// break;
+// case COUNTERPATTERN:
+// buildType = new BuildType("cntr");
+// break;
+// case LICENSEID:
+// case FAMILYID:
+// buildType = new BuildType("lst");
+// break;
+// default:
+// buildType = new BuildType("") {
+// @Override
+// protected String getMethodFormat(final AntOption antOption) {
+// return format("<%1$s>%%s%1$s>", tag);
+// }
+// };
+// }
+// ARG_TYPE_MAP.put(argType, buildType);
+// }
+// }
/**
* The prefix for the ant build.xml file.
@@ -158,7 +165,7 @@ public void setup() throws IOException {
}
private static String configFile(String fileName) {
- return format("", fileName);
+ return format("", fileName);
}
@ParameterizedTest(name = "{index} {0}")
@@ -221,24 +228,23 @@ private void executeTarget(StringBuilder outputBuffer, StringBuilder errorBuffer
static String targetName(AntOption option) {
AntOption actualOption = option.getActualAntOption();
- return actualOption.getName() + (actualOption.isAttribute() ? "Attribute" :"Element");
+ return actualOption.getName() + (actualOption.isAttribute() ? "Attribute" : "Element");
}
/**
* Generate the data for the tests.
+ *
* @return the arguments for the tests.
*/
static Stream generatedData() {
- List options = Arg.getOptions().getOptions().stream()
- .filter(o -> !AntOption.getFilteredOptions().contains(o)).map(AntOption::new)
- .toList();
+ List options = AntOptionCollection.INSTANCE.getMappedOptions().toList();
List lst = new ArrayList<>();
for (AntOption option : options) {
lst.add(createTest(option));
- option.convertedFrom().forEach(o -> lst.add(createTest(new AntOption(o))));
+ option.convertedFrom().forEach(o -> lst.add(createTest(o)));
}
for (Arguments arguments : lst) {
Object[] objects = arguments.get();
@@ -249,8 +255,8 @@ static Stream generatedData() {
private static Arguments createTest(AntOption option) {
AntOption actualOption = option.getActualAntOption();
- BuildType buildType = ARG_TYPE_MAP.get(option.getArgType());
- String xml = buildXml(actualOption, option, buildType.getXml(option));
+ AntOptionCollection.BuildType buildType = option.buildType();
+ String xml = buildXml(actualOption, option, buildType.getXml(option, getData(option)));
return Arguments.of(buildType.testName(option), xml, option);
}
@@ -278,7 +284,7 @@ private static String buildXml(AntOption actualOption, AntOption option, String
// if (actualOption.argCount() == 1) {
// xml.append(format(" <%s %s=\"%s\" />%n", actualOption.getName(), createAttribute(option), getData(option)));
// } else {
- xml.append(format(" <%1$s>%2$s%1$s>%n", actualOption.getName(), body));
+ xml.append(format(" <%1$s>%2$s%1$s>%n", actualOption.getName(), body));
// }
}
}
@@ -293,17 +299,22 @@ private static String buildXml(AntOption actualOption, AntOption option, String
return xml.toString();
}
- private static String getData(AntOption option) {
- String value = getData(option.getName());
+ private static String getData(AntOption antOption) {
+
+ String value = getData(ArgumentTracker.extractName(antOption.getOption()).toCase(CasedString.StringCase.PASCAL));
+
+ //String value = getData(antOption.getCasedName().toCase(CasedString.StringCase.PASCAL));
+
if (value == null) {
- if (!option.hasArg()) {
+ if (!antOption.hasArg()) {
return "true";
} else {
- throw new IllegalStateException("Missing " + option.getName());
+ throw new IllegalStateException("Missing " + antOption.getName());
}
}
return value;
}
+
private static String getData(String name) {
try {
return switch (name) {
@@ -394,6 +405,7 @@ private static class AntTestListener implements BuildListener {
private final int logLevel;
private final StringBuilder logBuffer;
private final StringBuilder fullLogBuffer;
+
/**
* Constructs a test listener which will ignore log events
* above the given level.
@@ -482,41 +494,4 @@ public void write(int b) {
buffer.append((char) b);
}
}
-
- public static class BuildType {
- /** The configuration tag for this build type */
- protected final String tag;
- /** If True adds the tag as the test extension */
- private final boolean addExt;
-
- BuildType(final String tag) {
- this(tag, StringUtils.isNotEmpty(tag));
- }
-
- BuildType(final String tag, boolean addExt) {
- this.tag = tag;
- this.addExt = addExt;
- }
-
- protected String getMultipleFormat(final AntOption antOption) {
- return String.format(" <%1$s>%%s%1$s>\n", tag);
- }
-
- protected String getMethodFormat(final AntOption antOption) {
- return antOption.hasArgs() ? getMultipleFormat(antOption) : String.format(" <%1$s>%%s%1$s>\n", tag);
- }
-
- public String testName(final AntOption antOption) {
- return addExt ? format("%s_%s", antOption.getName(), antOption.getArgName()) : antOption.getName();
- }
-
- public String getXml(final AntOption antOption) {
- AntOption delegateOption = antOption.getActualAntOption();
- if (delegateOption.isAttribute()) {
- return "";
- } else {
- return format(getMethodFormat(antOption), getData(antOption));
- }
- }
- }
}
diff --git a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/HelpTest.java b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/HelpTest.java
index 5b6a6903f..7006f32ea 100644
--- a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/HelpTest.java
+++ b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/HelpTest.java
@@ -46,9 +46,9 @@ protected File getAntFile() {
@Test
public void testExecHelp() {
buildRule.executeTarget("execHelp");
- System.out.println(buildRule.getOutput());
+ // System.out.println(buildRule.getOutput());
assertThat(buildRule.getOutput()).contains(" ");
- assertThat(buildRule.getOutput()).contains("File");
- assertThat(buildRule.getOutput()).contains("Deprecated for removal since 0.17: Use outputFamilies attribute instead.");
+ assertThat(buildRule.getOutput()).contains("File");
+ assertThat(buildRule.getOutput()).contains("Deprecated for removal since 0.17: Use outputFamilies attribute");
}
}
diff --git a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportOptionTest.java b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportOptionTest.java
index 9f66bc74d..08a2c407a 100644
--- a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportOptionTest.java
+++ b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportOptionTest.java
@@ -27,6 +27,7 @@
import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
+import org.apache.rat.documentation.options.AntOptionCollection;
import org.apache.rat.test.AbstractConfigurationOptionsProvider;
import org.apache.rat.OptionCollectionTest;
import org.apache.rat.ReportConfiguration;
@@ -119,11 +120,6 @@ protected ReportConfiguration generateConfig(final List>
return reportConfiguration;
}
- @Override
- protected void helpTest() {
- fail("Should not be called");
- }
-
@Override
public void helpLicenses() {
TestingLog testLog = new TestingLog();
@@ -146,7 +142,7 @@ private class BuildTask extends AbstractRatAntTaskTest {
final String name;
BuildTask(Option option) {
- this(new AntOption(option).getName());
+ this(AntOptionCollection.INSTANCE.getMappedOption(option).get().getName());
}
BuildTask() {
@@ -162,7 +158,7 @@ public final void setUp(List> args) {
Map attributes = new HashMap<>();
if (args.get(0).getKey() != null) {
for (Pair
pair : args) {
- AntOption argOption = new AntOption(pair.getKey());
+ AntOption argOption = AntOptionCollection.INSTANCE.getMappedOption(pair.getKey()).get();
if (argOption.isAttribute()) {
String value = pair.getValue() == null ? "true" : pair.getValue()[0];
attributes.put(argOption.getName(), value);
diff --git a/apache-rat-tools/pom.xml b/apache-rat-tools/pom.xml
index 728694d89..132c5674c 100644
--- a/apache-rat-tools/pom.xml
+++ b/apache-rat-tools/pom.xml
@@ -90,6 +90,10 @@
+
+ org.apache.commons
+ commons-text
+ org.apache.ratapache-rat-core
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AbstractOption.java b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AbstractOption.java
deleted file mode 100644
index 84335831c..000000000
--- a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AbstractOption.java
+++ /dev/null
@@ -1,233 +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.documentation.options;
-
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.cli.Option;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.rat.OptionCollection;
-import org.apache.rat.commandline.Arg;
-
-import static java.lang.String.format;
-
-/**
- * Abstract class that provides the framework for UI-specific RAT options.
- * In this context UI option means an option expressed in the specific UI, such as:
- * @see AntOption
- * @see MavenOption
- * @see CLIOption
- */
-public abstract class AbstractOption {
- /** The pattern to match CLI options in text */
- protected static final Pattern PATTERN = Pattern.compile("-(-[a-z0-9]+)+");
- /** The actual UI-specific name for the option */
- protected final Option option;
- /** The name for the option */
- protected final String name;
- /** The argument type for this option */
- protected final OptionCollection.ArgumentType argumentType;
-
- /**
- * Constructor.
- *
- * @param option The CLI option
- * @param name the UI-specific name for the option.
- */
- AbstractOption(final Option option, final String name) {
- this.option = option;
- this.name = name;
- argumentType = option.hasArg() ?
- option.getArgName() == null ? OptionCollection.ArgumentType.ARG :
- OptionCollection.ArgumentType.valueOf(option.getArgName().toUpperCase(Locale.ROOT)) :
- OptionCollection.ArgumentType.NONE;
- }
-
- /**
- * Gets the option this abstract option is wrapping.
- * @return the original Option.
- */
- public Option getOption() {
- return option;
- }
-
- /**
- * Return default value.
- * @return default value or {@code null} if no argument given.
- */
- public String getDefaultValue() {
- Arg arg = Arg.findArg(option);
- return arg == null ? null : arg.defaultValue();
- }
-
- /**
- * Provide means to wrap the given option depending on the UI-specific option implementation.
- * @param option The CLI option
- * @return the cleaned up option name.
- */
- protected abstract String cleanupName(Option option);
-
- /**
- * Gets an example of how to use this option in the native UI.
- * @return An example of how to use this option in the native UI.
- */
- public abstract String getExample();
-
- /**
- * Gets this option's cleaned up name.
- * @return This option's cleaned up name.
- */
- public String cleanupName() {
- return cleanupName(option);
- }
-
- /**
- * Replaces CLI pattern options with implementation specific pattern options.
- * @param str the string to clean.
- * @return the string with CLI names replaced with implementation specific names.
- */
- public String cleanup(final String str) {
- String workingStr = str;
- if (StringUtils.isNotBlank(workingStr)) {
- Map maps = new HashMap<>();
- Matcher matcher = PATTERN.matcher(workingStr);
- while (matcher.find()) {
- String key = matcher.group();
- String optKey = key.substring(2);
- Optional
maybeResult = Arg.getOptions().getOptions().stream()
- .filter(o -> optKey.equals(o.getOpt()) || optKey.equals(o.getLongOpt())).findFirst();
- maybeResult.ifPresent(value -> maps.put(key, cleanupName(value)));
- }
- for (Map.Entry entry : maps.entrySet()) {
- workingStr = workingStr.replaceAll(Pattern.quote(format("%s", entry.getKey())), entry.getValue());
- }
- }
- return workingStr;
- }
-
- /**
- * Gets the implementation specific name for the CLI option.
- * @return The implementation specific name for the CLI option.
- */
- public final String getName() {
- return name;
- }
-
- /**
- * return a string showing long and short options if they are available. Will return
- * a string.
- * @return A string showing long and short options if they are available. Never {@code null}.
- */
- public abstract String getText();
-
- /**
- * Gets the description in implementation specific format.
- *
- * @return the description or an empty string.
- */
- public final String getDescription() {
- return cleanup(option.getDescription());
- }
-
- /**
- * Gets the simple class name for the data type for this option.
- * Normally "String".
- * @return the simple class name for the type.
- */
- public final Class> getType() {
- return option.hasArg() ? ((Class>) option.getType()) : boolean.class;
- }
-
- /**
- * Gets the argument name if there is one.
- * @return the Argument name
- */
- public final String getArgName() {
- return argumentType.getDisplayName();
- }
-
- /**
- * Gets the argument type if there is one.
- * @return the Argument name
- */
- public final OptionCollection.ArgumentType getArgType() {
- return argumentType;
- }
-
- /**
- * Determines if the option is deprecated.
- * @return {@code true} if the option is deprecated
- */
- public final boolean isDeprecated() {
- return option.isDeprecated();
- }
-
- /**
- * Determines if the option is required.
- * @return {@code true} if the option is required.
- */
- public final boolean isRequired() {
- return option.isRequired();
- }
-
- /**
- * Determine if the enclosed option expects an argument.
- * @return {@code true} if the enclosed option expects at least one argument.
- */
- public final boolean hasArg() {
- return option.hasArg();
- }
-
- /**
- * Returns {@code true} if the option has multiple arguments.
- * @return {@code true} if the option has multiple arguments.
- */
- public final boolean hasArgs() {
- return option.hasArgs();
- }
-
- /**
- * Returns the number of arguments.
- * @return The number of arguments.
- */
- public final int argCount() {
- return option.getArgs();
- }
-
- /**
- * The key value for the option.
- * @return the key value for the CLI argument map.
- */
- public final String keyValue() {
- return format("\"%s\"", StringUtils.defaultIfEmpty(option.getLongOpt(), option.getOpt()));
- }
-
- /**
- * Gets the deprecated string if the option is deprecated, or an empty string otherwise.
- * @return the deprecated string if the option is deprecated, or an empty string otherwise.
- */
- public final String getDeprecated() {
- return option.isDeprecated() ? cleanup(StringUtils.defaultIfEmpty(option.getDeprecated().toString(), StringUtils.EMPTY)) : StringUtils.EMPTY;
- }
-}
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AntOption.java b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AntOption.java
index 38e88ba21..491f0f442 100644
--- a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AntOption.java
+++ b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AntOption.java
@@ -18,199 +18,29 @@
*/
package org.apache.rat.documentation.options;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
-import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
import org.apache.commons.cli.Option;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.text.StringEscapeUtils;
-import org.apache.commons.text.WordUtils;
-import org.apache.rat.OptionCollection;
-import org.apache.rat.commandline.Arg;
-import org.apache.rat.utils.CasedString;
+import org.apache.rat.ui.UIOption;
+import org.apache.rat.ui.UIOptionCollection;
import static java.lang.String.format;
/**
* A class that wraps the CLI option and provides Ant specific values.
*/
-public class AntOption extends AbstractOption {
-
- /**
- * The filter to filter out CLI options that Ant does not support.
- */
- private static final Predicate
ANT_FILTER;
-
- /**
- * The list of Options that are not supported by Ant.
- */
- private static final List
UNSUPPORTED_LIST = new ArrayList<>();
-
- /**
- * The mapping of option to the implementation option in Ant.
- */
- private static final Map
ANT_CONVERSION_MAP = new HashMap<>();
-
- /**
- * The list of example patterns for various classes.
- */
- private static final Map BUILD_TYPE_MAP = new HashMap<>();
-
- /** The list of attribute types. */
- private static final List> ATTRIBUTE_TYPES = new ArrayList<>();
- /** A mapping of external name to internal name if not standard. */
- private static final Map RENAME_MAP = new HashMap<>();
-
- /** Attributes that are required for example data. */
- private static final Map> REQUIRED_ATTRIBUTES = new HashMap<>();
-
- /**
- * Adds a mapping from the specified Arg to the Arg to be used for generation.
- * @param arg the arg to map.
- * @param actualArg the Arg to map {@code arg} to.
- */
- private static void updateConversionMap(final Arg arg, final Arg actualArg) {
- Option mapTo = actualArg.option();
- for (Option option : arg.group().getOptions()) {
- if (!option.equals(mapTo) && !option.isDeprecated()) {
- ANT_CONVERSION_MAP.put(option, mapTo);
- }
- }
- }
-
- static {
- RENAME_MAP.put("addLicense", "add-license");
- ATTRIBUTE_TYPES.add(String.class);
- ATTRIBUTE_TYPES.add(String[].class);
- ATTRIBUTE_TYPES.add(Integer.class);
- ATTRIBUTE_TYPES.add(Long.class);
- ATTRIBUTE_TYPES.add(File.class);
- Arg.getOptions().getOptions().stream().filter(o -> Objects.isNull(o.getLongOpt())).forEach(UNSUPPORTED_LIST::add);
- UNSUPPORTED_LIST.addAll(Arg.LOG_LEVEL.group().getOptions());
- UNSUPPORTED_LIST.addAll(Arg.DIR.group().getOptions());
- UNSUPPORTED_LIST.add(OptionCollection.HELP);
- UNSUPPORTED_LIST.addAll(Arg.SOURCE.group().getOptions());
- updateConversionMap(Arg.LICENSES_APPROVED_FILE, Arg.LICENSES_APPROVED);
- updateConversionMap(Arg.LICENSES_DENIED_FILE, Arg.LICENSES_DENIED);
- updateConversionMap(Arg.FAMILIES_APPROVED_FILE, Arg.FAMILIES_APPROVED);
- updateConversionMap(Arg.FAMILIES_DENIED_FILE, Arg.FAMILIES_DENIED);
- updateConversionMap(Arg.INCLUDE_FILE, Arg.INCLUDE);
- updateConversionMap(Arg.INCLUDE_STD, Arg.INCLUDE);
- updateConversionMap(Arg.EXCLUDE_FILE, Arg.EXCLUDE);
- updateConversionMap(Arg.EXCLUDE_STD, Arg.EXCLUDE);
-
- /*
- * Create the BuildTypes for the Argument types.
- */
- BuildType buildType;
- for (OptionCollection.ArgumentType type : OptionCollection.ArgumentType.values()) {
- switch (type) {
- case FILE:
- case DIRORARCHIVE:
- buildType = new BuildType(type, "filename") {
- @Override
- protected String getMultipleFormat(final AntOption antOption) {
- return " \n";
- }
- };
- BUILD_TYPE_MAP.put(type, buildType);
- break;
- case NONE:
- buildType = new BuildType(type, "");
- BUILD_TYPE_MAP.put(type, buildType);
- break;
- case COUNTERPATTERN:
- buildType = new BuildType(type, "cntr");
- BUILD_TYPE_MAP.put(type, buildType);
- break;
- case EXPRESSION:
- buildType = new BuildType(type, "expr");
- BUILD_TYPE_MAP.put(type, buildType);
- break;
- case STANDARDCOLLECTION:
- buildType = new BuildType(type, "std");
- BUILD_TYPE_MAP.put(type, buildType);
- break;
- case LICENSEID:
- case FAMILYID:
- buildType = new BuildType(type, "lst");
- BUILD_TYPE_MAP.put(type, buildType);
- break;
- default:
- buildType = new BuildType(type, type.getDisplayName()) {
- protected String getMethodFormat(final AntOption antOption) {
- return String.format("<%1$s>%%s%1$s>%n", WordUtils.uncapitalize(antOption.getArgName()));
- }
- };
- BUILD_TYPE_MAP.put(type, buildType);
- }
- }
- Set
filteredOptions = getFilteredOptions();
- ANT_FILTER = option -> !(filteredOptions.contains(option) || option.getLongOpt() == null);
-
- Map attributes = new HashMap<>();
- attributes.put("editLicense", "true");
- REQUIRED_ATTRIBUTES.put("copyright", attributes);
- REQUIRED_ATTRIBUTES.put("editCopyright", attributes);
- REQUIRED_ATTRIBUTES.put("force", attributes);
- REQUIRED_ATTRIBUTES.put("editOverwrite", attributes);
- }
-
- /**
- * Gets the list of all available Ant options.
- * @return the list of all available Ant options.
- */
- public static List getAntOptions() {
- return Arg.getOptions().getOptions().stream().filter(ANT_FILTER).map(AntOption::new)
- .collect(Collectors.toList());
- }
- /**
- * Gets the list of unsupported options.
- * @return the list of unsupported options.
- */
- public static List
getUnsupportedOptions() {
- return Collections.unmodifiableList(UNSUPPORTED_LIST);
- }
-
- /**
- * Gets the set of options that are not supported by Ant either by not being supported or
- * by being converted to another argument.
- * @return The set of options that are not supported by Ant.
- */
- public static Set
getFilteredOptions() {
- HashSet
filteredOptions = new HashSet<>(UNSUPPORTED_LIST);
- filteredOptions.addAll(ANT_CONVERSION_MAP.keySet());
- return filteredOptions;
- }
-
- public static Map getRenameMap() {
- return Collections.unmodifiableMap(RENAME_MAP);
- }
+public class AntOption extends UIOption {
/**
* Constructor.
*
* @param option the option to wrap.
*/
- public AntOption(final Option option) {
- super(option, createName(option));
- }
-
- public static String createName(final Option option) {
- String name = option.getLongOpt();
- name = StringUtils.defaultIfEmpty(RENAME_MAP.get(name), name).toLowerCase(Locale.ROOT);
- return new CasedString(CasedString.StringCase.KEBAB, name).toCase(CasedString.StringCase.PASCAL);
+ public AntOption(final UIOptionCollection collection, final Option option) {
+ super(collection, option, AntOptionCollection.createName(option));
}
/**
@@ -219,8 +49,7 @@ public static String createName(final Option option) {
* @return {@code true} if the option should be an attribute of the <rat:report> element.
*/
public boolean isAttribute() {
- return (!option.hasArg() || option.getArgs() == 1) && convertedFrom().isEmpty()
- && ATTRIBUTE_TYPES.contains(option.getType());
+ return getAntCollection().isAttribute(this);
}
/**
@@ -238,18 +67,15 @@ public boolean isElement() {
* @return the converted option.
*/
public AntOption getActualAntOption() {
- Option opt = ANT_CONVERSION_MAP.get(this.option);
- return opt == null ? this : new AntOption(opt);
+ return getAntCollection().getActualAntOption(this);
}
/**
* Gets the set of options that are mapped to this option.
* @return the set of options that are mapped to this option.
*/
- public Set
convertedFrom() {
- return ANT_CONVERSION_MAP.entrySet().stream().filter(e -> e.getValue().equals(option))
- .map(Map.Entry::getKey)
- .collect(Collectors.toSet());
+ public Set convertedFrom() {
+ return getAntCollection().convertedFrom(this);
}
@Override
@@ -257,122 +83,38 @@ public String getText() {
return cleanupName(option);
}
+ @Override
protected String cleanupName(final Option option) {
- AntOption antOption = new AntOption(option);
- String fmt = antOption.isAttribute() ? "%s attribute" : "<%s>";
- return format(fmt, createName(option));
- }
-
- /**
- * Get the method comment for this option.
- *
- * @param addParam if {@code true} the param annotation is added.
- * @return the Comment block for the function.
- */
- public String getComment(final boolean addParam) {
- StringBuilder sb = new StringBuilder();
- String desc = getDescription();
- if (desc == null) {
- throw new IllegalStateException(format("Description for %s may not be null", getName()));
- }
- if (!desc.contains(".")) {
- throw new IllegalStateException(format("First sentence of description for %s must end with a '.'", getName()));
- }
- if (addParam) {
- String arg;
- if (option.hasArg()) {
- arg = desc.substring(desc.indexOf(" ") + 1, desc.indexOf(".") + 1);
- arg = WordUtils.capitalize(arg.substring(0, 1)) + arg.substring(1);
+ AntOption antOption;
+ if (getOption().equals(option)) {
+ antOption = this;
+ } else {
+ Optional optAntOption = getOptionCollection().getMappedOption(option);
+ if (optAntOption.isPresent()) {
+ antOption = optAntOption.get();
} else {
- arg = "The state";
- }
- if (option.getArgName() != null) {
- Supplier sup = OptionCollection.getArgumentTypes().get(option.getArgName());
- if (sup == null) {
- throw new IllegalStateException(format("Argument type %s must be in OptionCollection.ARGUMENT_TYPES", option.getArgName()));
- }
- desc = format("%s Argument%s should be %s%s. (See Argument Types for clarification)", desc, option.hasArgs() ? "s" : "",
- option.hasArgs() ? "" : "a ", option.getArgName());
+ return "";
}
- sb.append(format(" /**%n * %s%n * @param %s %s%n", StringEscapeUtils.escapeHtml4(desc), getName(),
- StringEscapeUtils.escapeHtml4(arg)));
- } else {
- sb.append(format(" /**%n * %s%n", StringEscapeUtils.escapeHtml4(desc)));
- }
- if (option.isDeprecated()) {
- sb.append(format(" * @deprecated %s%n", StringEscapeUtils.escapeHtml4(getDeprecated())));
}
- return sb.append(format(" */%n")).toString();
+ return antOption.cleanupName();
}
- /**
- * Get the signature of the attribute function.
- *
- * @return the signature of the attribute function.
- */
- public String getAttributeFunctionName() {
- return "set" +
- WordUtils.capitalize(name) +
- (option.hasArg() ? "(String " : "(boolean ") +
- name +
- ")";
+ public String cleanupName() {
+ String fmt = isAttribute() ? "%s attribute" : "<%s>";
+ return format(fmt, name);
}
- @Override
- public String getExample() {
- return new ExampleGenerator().getExample();
+ AntOptionCollection getAntCollection() {
+ return getOptionCollection();
}
- /**
- * A mapping of data type of XML format.
- */
- private static class BuildType {
- /** The argument type associated with their build type */
- private final OptionCollection.ArgumentType type;
- /** The configuration tag for this build type */
- private final String tag;
-
- /**
- * The constructor for the build type.
- * @param type the ArgumentType as specified in the OptionCollection.
- * @param tag the XML tag for this data type.
- */
- BuildType(final OptionCollection.ArgumentType type, final String tag) {
- this.type = type;
- this.tag = tag;
- }
-
- /**
- * Returns the format used when multiple arguments are expected by an Ant option.
- * @param antOption the Ant option to check.
- * @return the format used for multiple arguments.
- */
- protected String getMultipleFormat(final AntOption antOption) {
- return String.format("<%1$s>%%s%1$s>%n", tag);
- }
-
- /**
- * Gets the method based on how many arguments an Ant option requires.
- * @param antOption the Ant option to check.
- * @return the method format for the option.
- */
- protected String getMethodFormat(final AntOption antOption) {
- return antOption.hasArgs() ? getMultipleFormat(antOption) : String.format("<%1$s>%%s%1$s>%n", tag);
- }
+ public AntOptionCollection.BuildType buildType() {
+ return getAntCollection().buildType(this.getArgType());
+ }
- /**
- * Gets a string comprising the Ant XML pattern for this data type and the number of arguments expected by the Ant option.
- * @param delegateOption the Ant option that the call is delegated to.
- * @param antOption the actual ant option.
- * @param data the data for the actual ant option.
- * @return the Ant XML pattern for this data type.
- */
- public String getPattern(final AntOption delegateOption, final AntOption antOption, final String data) {
- String fmt = getMethodFormat(antOption);
- String value = data == null ? WordUtils.uncapitalize(antOption.getArgName()) : data;
- String inner = format(fmt, value);
- return format("<%1$s>%2$s%1$s>%n", delegateOption.getName(), inner);
- }
+ @Override
+ public String getExample() {
+ return new ExampleGenerator().getExample();
}
/**
@@ -391,7 +133,7 @@ public ExampleGenerator() {
* @return the example of this ant option.
*/
String getExample() {
- return getExample("data", REQUIRED_ATTRIBUTES.get(getName()), null);
+ return getExample("data", getAntCollection().getRequiredAttributes(getName()), null);
}
/**
@@ -402,9 +144,6 @@ String getExample() {
* @return example Ant XML report call using ant option with the specified attributes and child elements.
*/
public String getExample(final String data, final Map attributes, final List childElements) {
- if (UNSUPPORTED_LIST.contains(option)) {
- return "-- not supported --";
- }
return " \n" +
@@ -441,7 +180,7 @@ public String getChildElements(final String data, final List childElemen
AntOption actualOption = getActualAntOption();
StringBuilder result = new StringBuilder();
if (!actualOption.isAttribute()) {
- String inner = BUILD_TYPE_MAP.get(getArgType()).getPattern(actualOption, baseOption, data);
+ String inner = getAntCollection().buildType(getArgType()).getXml(actualOption, baseOption, data);
result.append(inner);
}
if (childElements != null) {
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/CLIOption.java b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/CLIOption.java
deleted file mode 100644
index 5ac78b82e..000000000
--- a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/CLIOption.java
+++ /dev/null
@@ -1,71 +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
- *
- * https://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.documentation.options;
-
-import org.apache.commons.cli.Option;
-import org.apache.commons.lang3.StringUtils;
-
-public class CLIOption extends AbstractOption {
-
- public static String createName(final Option option) {
- return StringUtils.defaultIfBlank(option.getLongOpt(), option.getOpt());
- }
-
- public CLIOption(final Option option) {
- super(option, createName(option));
- }
-
- @Override
- public String getText() {
- StringBuilder result = new StringBuilder();
- if (option.getLongOpt() != null) {
- result.append("--").append(option.getLongOpt());
- if (option.getOpt() != null) {
- result.append(" or -").append(option.getArgs());
- }
- } else {
- result.append("-").append(option.getArgs());
- }
- return result.toString();
- }
-
- @Override
- protected String cleanupName(final Option option) {
- return createName(option);
- }
-
- @Override
- public String getExample() {
- StringBuilder sb = new StringBuilder("-");
- if (option.getLongOpt() != null) {
- sb.append("-").append(option.getLongOpt());
- } else {
- sb.append(option.getOpt());
- }
- if (option.hasArg()) {
- String argName = StringUtils.defaultIfBlank(option.getArgName(), "Arg");
- sb.append(" ").append(argName);
- if (option.hasArgs()) {
- sb.append(" [").append(argName).append("2 [").append(argName)
- .append("3 [...]]] --");
- }
- }
- return sb.toString();
- }
-}
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/MavenOption.java b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/MavenOption.java
index 4644297ca..fb2b24608 100644
--- a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/MavenOption.java
+++ b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/MavenOption.java
@@ -18,97 +18,49 @@
*/
package org.apache.rat.documentation.options;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
import org.apache.commons.cli.Option;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.WordUtils;
-import org.apache.rat.OptionCollection;
-import org.apache.rat.commandline.Arg;
+import org.apache.rat.ui.UIOption;
+import org.apache.rat.ui.UIOptionCollection;
import org.apache.rat.utils.CasedString;
import static java.lang.String.format;
/**
- * A representation of a CLI option as a Maven option
+ * A representation of a Maven option based on a CLI option.
*/
-public class MavenOption extends AbstractOption {
- /**
- * Default values for CLI options
- */
- private static final Map DEFAULT_VALUES = new HashMap<>();
- /**
- * List of CLI options that are not supported by Maven.
- */
- private static final Set
UNSUPPORTED_LIST = new HashSet<>();
- /** A mapping of external name to internal name if not standard. */
- private static final Map RENAME_MAP = new HashMap<>();
-
- /**
- * Filter to remove options not supported by Maven.
- */
- private static final Predicate
filteredOptions = getFilteredOptions();
- MAVEN_FILTER = option -> !(filteredOptions.contains(option) || option.getLongOpt() == null);
- }
-
- public static List getMavenOptions() {
- return OptionCollection.buildOptions().getOptions().stream().filter(MAVEN_FILTER)
- .map(MavenOption::new).collect(Collectors.toList());
- }
+public final class MavenOption extends UIOption {
/**
* Constructor.
*
* @param option The CLI option
*/
- public MavenOption(final Option option) {
- super(option, createName(option));
- }
-
- public static Map getRenameMap() {
- return Collections.unmodifiableMap(RENAME_MAP);
+ MavenOption(final UIOptionCollection collection, final Option option) {
+ super(collection, option, MavenOptionCollection.createName(option));
}
- /**
- * Gets the set of options that are not supported by Maven.
- *
- * @return The set of options that are not supported by Maven.
- */
- public static Set
getFilteredOptions() {
- return Collections.unmodifiableSet(UNSUPPORTED_LIST);
+ @Override
+ public String toString() {
+ return getName();
}
/**
- * Creates the Maven element name for the specified option.
- * @param option The option to process.
- * @return the Maven based name in camel-case syntax.
+ * Gets the method name for this option.
+ * @return the method name for this option.
*/
- 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);
+ public String getMethodName() {
+ return "set" + name.toCase(CasedString.StringCase.PASCAL);
}
@Override
protected String cleanupName(final Option option) {
- return format("<%s>", createName(option));
+ // only parse the option if we need to.
+ if (option == this.option) {
+ return format("<%s>", this.name);
+ }
+ return format("<%s>", ((MavenOptionCollection) getOptionCollection()).createName(option));
}
@Override
@@ -117,29 +69,36 @@ public String getText() {
}
@Override
- public String getDefaultValue() {
- Arg arg = Arg.findArg(option);
- String result = DEFAULT_VALUES.get(arg);
- if (result == null) {
- result = arg.defaultValue();
+ public String getExample() {
+ if (hasArgs()) {
+ return getExample(new String[]{getArgName() + "1", getArgName() + "2"});
+ }
+ if (hasArg()) {
+ return getExample(getArgName());
}
- return result;
+ return getExample("");
}
- public String getPropertyAnnotation(final String fname) {
- StringBuilder sb = new StringBuilder("@Parameter");
- String property = option.hasArgs() ? null : format("property = \"rat.%s\"", fname);
- String defaultValue = option.isDeprecated() ? null : getDefaultValue();
- if (property != null || defaultValue != null) {
- sb.append("(");
- if (property != null) {
- sb.append(property).append(defaultValue != null ? ", " : StringUtils.EMPTY);
- }
- if (defaultValue != null) {
- sb.append(format("defaultValue = \"%s\"", defaultValue));
+ /**
+ * Create example text for the option.
+ * @param args the example arguments for the option.
+ * @return a formatted option.
+ */
+ public String getExample(final String... args) {
+ StringBuilder sb = new StringBuilder(String.format("<%s>", getName()));
+ if (hasArg()) {
+ if (hasArgs()) {
+ sb.append(System.lineSeparator());
+ for (String arg : args) {
+ sb.append(String.format(" <%1$s>%2$s%1$s>%n", WordUtils.uncapitalize(getArgName()), arg));
+ }
+ } else {
+ sb.append(args[0]);
}
- sb.append(")");
+ } else {
+ sb.append(Boolean.TRUE);
}
+ sb.append("").append(getName()).append(">");
return sb.toString();
}
@@ -148,7 +107,7 @@ public String getMethodSignature(final String indent, final boolean multiple) {
if (isDeprecated()) {
sb.append(format("%s@Deprecated%n", indent));
}
- String fname = WordUtils.capitalize(name);
+ String fname = name.toCase(CasedString.StringCase.CAMEL).toString();
String args = option.hasArg() ? "String" : "boolean";
if (multiple) {
if (!(fname.endsWith("s") || fname.endsWith("Approved") || fname.endsWith("Denied"))) {
@@ -162,15 +121,22 @@ indent, name, fname, args, getPropertyAnnotation(fname)))
.toString();
}
- @Override
- public String getExample() {
- if (UNSUPPORTED_LIST.contains(option)) {
- return "-- not supported --";
- }
- if (hasArg()) {
- return format("<%1$s>%2$s%1$s>", getName(), getArgName());
- } else {
- return format("<%s />", getName());
+
+ public String getPropertyAnnotation(final String fname) {
+ StringBuilder sb = new StringBuilder("@Parameter");
+ String property = option.hasArgs() ? null : format("property = \"rat.%s\"", fname);
+ String defaultValue = option.isDeprecated() ? null : getDefaultValue();
+ if (property != null || defaultValue != null) {
+ sb.append("(");
+ if (property != null) {
+ sb.append(property).append(defaultValue != null ? ", " : StringUtils.EMPTY);
+ }
+ if (defaultValue != null) {
+ sb.append(format("defaultValue = \"%s\"", defaultValue));
+ }
+ sb.append(")");
}
+ return sb.toString();
}
+
}
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/MavenOptionCollection.java b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/MavenOptionCollection.java
new file mode 100644
index 000000000..9c13362dd
--- /dev/null
+++ b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/MavenOptionCollection.java
@@ -0,0 +1,114 @@
+/*
+ * 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
+ *
+ * https://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.documentation.options;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+
+import org.apache.commons.cli.Option;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rat.commandline.Arg;
+import org.apache.rat.ui.ArgumentTracker;
+import org.apache.rat.ui.UIOptionCollection;
+import org.apache.rat.utils.CasedString;
+
+/**
+ * The collection of MavenOptions equivalent to the CLI options
+ * with any unsupported options removed.
+ */
+public final class MavenOptionCollection extends UIOptionCollection {
+ /** mapping of standard name to non-conflicting name. */
+ private static final Map RENAME_MAP;
+
+ static {
+ Map map = new HashMap<>();
+ map.put("addLicense", "add-license");
+ RENAME_MAP = map;
+ }
+
+ /** The instance of the MavenOptionCollection */
+ public static final MavenOptionCollection INSTANCE = new Builder().build();
+
+ public static Map getRenameMap() {
+ return new TreeMap<>(RENAME_MAP);
+ }
+
+ /**
+ * Create an Instance.
+ */
+ private MavenOptionCollection(final Builder builder) {
+ super(builder);
+ }
+
+
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Provides a new name for an option if it is renamed in the collection.
+ * @param name the option name.
+ * @return the collection name, may be the same as the option name.
+ */
+ static String rename(final String name) {
+ return StringUtils.defaultIfEmpty(RENAME_MAP.get(name), name);
+ }
+
+ /**
+ * Creates the name for the option based on rules for conversion of CLI option names.
+ * @param option the standard option.
+ * @return the new Option name as a CasedString.
+ */
+ static CasedString createName(final Option option) {
+ List 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.PASCAL);
+ }
+
+ /**
+ * The Builder for the MavenOptionCollection.
+ */
+ public static final class Builder extends UIOptionCollection.Builder {
+ private Builder() {
+ super();
+ Arg.getOptions().getOptions()
+ .stream().filter(o -> Objects.isNull(o.getLongOpt()))
+ .forEach(this::unsupported);
+ unsupported(Arg.DIR).unsupported(Arg.LOG_LEVEL)
+ .mapper((collection, option) -> new MavenOption(collection, option));
+ }
+
+ public MavenOptionCollection build() {
+ return new MavenOptionCollection(this);
+ }
+ }
+}
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/documentation/velocity/RatTool.java b/apache-rat-tools/src/main/java/org/apache/rat/documentation/velocity/RatTool.java
index 317d6c250..87c621715 100644
--- a/apache-rat-tools/src/main/java/org/apache/rat/documentation/velocity/RatTool.java
+++ b/apache-rat-tools/src/main/java/org/apache/rat/documentation/velocity/RatTool.java
@@ -25,12 +25,13 @@
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
-import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.apache.commons.cli.Option;
import org.apache.commons.lang3.StringUtils;
+import org.apache.rat.CLIOption;
+import org.apache.rat.CLIOptionCollection;
import org.apache.rat.Defaults;
import org.apache.rat.OptionCollection;
import org.apache.rat.api.EnvVar;
@@ -41,8 +42,9 @@
import org.apache.rat.config.parameters.DescriptionBuilder;
import org.apache.rat.configuration.MatcherBuilderTracker;
import org.apache.rat.documentation.options.AntOption;
-import org.apache.rat.documentation.options.CLIOption;
+import org.apache.rat.documentation.options.AntOptionCollection;
import org.apache.rat.documentation.options.MavenOption;
+import org.apache.rat.documentation.options.MavenOptionCollection;
import org.apache.rat.help.AbstractHelp;
import org.apache.rat.license.ILicense;
import org.apache.rat.license.LicenseSetFactory;
@@ -94,9 +96,8 @@ public RatTool() {
* @return the list of command line options.
*/
public List
options() {
- List
lst = new ArrayList<>(OptionCollection.buildOptions().getOptions());
- lst.sort(Comparator.comparing(CLIOption::createName));
- return lst;
+ return CLIOptionCollection.INSTANCE.getMappedOptions()
+ .map(CLIOption::getOption).toList();
}
/**
@@ -104,11 +105,7 @@ public List
options() {
* @return a map client option name to Ant Option.
*/
public Map antOptions() {
- Map result = new TreeMap<>();
- for (AntOption antOption : AntOption.getAntOptions()) {
- result.put(CLIOption.createName(antOption.getOption()), antOption);
- }
- return result;
+ return AntOptionCollection.INSTANCE.getOptionMap();
}
/**
@@ -116,12 +113,7 @@ public Map antOptions() {
* @return a map client option name to CLI Option.
*/
public Map cliOptions() {
- Map result = new TreeMap<>();
- for (Option option : OptionCollection.buildOptions().getOptions()) {
- CLIOption cliOption = new CLIOption(option);
- result.put(cliOption.getName(), cliOption);
- }
- return result;
+ return CLIOptionCollection.INSTANCE.getOptionMap();
}
/**
@@ -129,11 +121,7 @@ public Map cliOptions() {
* @return a map client option name to Maven Option.
*/
public Map mvnOptions() {
- Map result = new TreeMap<>();
- for (MavenOption mavenOption : MavenOption.getMavenOptions()) {
- result.put(CLIOption.createName(mavenOption.getOption()), mavenOption);
- }
- return result;
+ return MavenOptionCollection.INSTANCE.getOptionMap();
}
/**
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/tools/AntDocumentation.java b/apache-rat-tools/src/main/java/org/apache/rat/tools/AntDocumentation.java
index 9549bda63..a21b5a36c 100644
--- a/apache-rat-tools/src/main/java/org/apache/rat/tools/AntDocumentation.java
+++ b/apache-rat-tools/src/main/java/org/apache/rat/tools/AntDocumentation.java
@@ -30,15 +30,13 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.function.Predicate;
-import java.util.function.Supplier;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.rat.OptionCollection;
import org.apache.rat.documentation.options.AntOption;
+import org.apache.rat.documentation.options.AntOptionCollection;
import org.apache.rat.utils.DefaultLog;
import static java.lang.String.format;
@@ -84,8 +82,7 @@ private AntDocumentation(final File outputDir) {
}
public void execute() {
- List options = AntOption.getAntOptions();
-
+ List options = AntOptionCollection.INSTANCE.getMappedOptions().toList();
writeAttributes(options);
writeElements(options);
printValueTypes();
@@ -151,9 +148,9 @@ private void printValueTypes() {
List> table = new ArrayList<>();
table.add(Arrays.asList("Value Type", "Description"));
- for (Map.Entry> argInfo : OptionCollection.getArgumentTypes().entrySet()) {
- table.add(Arrays.asList(argInfo.getKey(), argInfo.getValue().get()));
- }
+ AntOptionCollection.INSTANCE.getMappedOptions()
+ .map(antOption -> Arrays.asList(antOption.getName(), antOption.getDescription()))
+ .forEach(table::add);
AptFormat.writeTable(writer, table, "*--+--+");
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/tools/AntGenerator.java b/apache-rat-tools/src/main/java/org/apache/rat/tools/AntGenerator.java
index c9bb7aaf5..884bdfb0c 100644
--- a/apache-rat-tools/src/main/java/org/apache/rat/tools/AntGenerator.java
+++ b/apache-rat-tools/src/main/java/org/apache/rat/tools/AntGenerator.java
@@ -27,19 +27,21 @@
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Supplier;
import org.apache.commons.cli.Option;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
import org.apache.commons.text.WordUtils;
import org.apache.rat.OptionCollection;
import org.apache.rat.documentation.options.AntOption;
+import org.apache.rat.documentation.options.AntOptionCollection;
import org.apache.rat.utils.CasedString;
import org.apache.rat.utils.CasedString.StringCase;
@@ -51,63 +53,49 @@
public final class AntGenerator {
/**
- * A map of type patterns for that type.
+ * Create a GenerateType for the option
+ * @param antOption the ant option to generate the type for.
*/
- private static final Map GENERATE_TYPE_MAP = new HashMap<>();
-
- static {
- String defaultFmt = " public void add%$1s(String %2$s) {%n" +
- " addArg(%%1$s, %2$s);%n" +
- " }%n%n";
- GenerateType generateType;
- for (OptionCollection.ArgumentType type : OptionCollection.ArgumentType.values()) {
- switch (type) {
- case FILE:
- case DIRORARCHIVE:
- generateType = new GenerateType("fileset") {
- protected String getMethodFormat(final AntOption antOption) {
- return """
- public void addConfiguredFileset(FileSet fileSet) {
- for (Resource resource : fileSet) {
- if (resource.isFilesystemOnly()) {
- addArg(%1$s, ((FileResource) resource).getFile().getAbsolutePath());
- }
- }
- }
- """;
+ private static GenerateType getGenerateType(final AntOption antOption) {
+ String defaultFmt = """
+ public void add%$1s(String %2$s) {
+ addArg(%%1$s, %2$s);
}
- };
- break;
- case NONE:
- generateType = new GenerateType("") {
- protected String getMethodFormat(final AntOption antOption) {
- return "";
- }
- };
- break;
- case STANDARDCOLLECTION:
- generateType = new GenerateType("Std");
- break;
- case EXPRESSION:
- generateType = new GenerateType("Expr");
- break;
- case COUNTERPATTERN:
- generateType = new GenerateType("Cntr");
- break;
- case LICENSEID:
- case FAMILYID:
- generateType = new GenerateType("Lst");
- break;
- default:
- generateType = new GenerateType(type.getDisplayName()) {
+ """;
- protected String getMethodFormat(final AntOption antOption) {
- return String.format(defaultFmt, innerClass, WordUtils.uncapitalize(antOption.getArgName()));
- }
- };
- }
- GENERATE_TYPE_MAP.put(type, generateType);
- }
+ GenerateType generateType = null;
+ return switch (antOption.getArgType()) {
+ case FILE, DIRORARCHIVE -> new GenerateType("FileSet") {
+ @Override
+ public String getMethod(final AntOption antOption) {
+ return format("""
+ public void addConfiguredFileset(FileSet fileSet) {
+ for (Resource resource : fileSet) {
+ if (resource.isFilesystemOnly()) {
+ addArg("%1$s", ((FileResource) resource).getFile().getAbsolutePath());
+ }
+ }
+ }
+ """, antOption.keyValue());
+ }
+ };
+ case NONE -> new GenerateType("") {
+ @Override
+ public String getMethod(final AntOption antOption) {
+ return "";
+ }
+ };
+ case STANDARDCOLLECTION -> new GenerateType("Std");
+ case EXPRESSION -> new GenerateType("Expr");
+ case COUNTERPATTERN -> new GenerateType("Cntr");
+ case LICENSEID, FAMILYID -> new GenerateType("Lst");
+ default -> new GenerateType(antOption.getArgType().getDisplayName()) {
+ @Override
+ public String getMethod(final AntOption antOption) {
+ return String.format(defaultFmt, innerClass, WordUtils.uncapitalize(antOption.getArgName()));
+ }
+ };
+ };
}
private AntGenerator() { }
@@ -142,7 +130,7 @@ public static void main(final String[] args) throws IOException {
String className = args[1];
String destDir = args[2];
- List options = AntOption.getAntOptions();
+ List options = AntOptionCollection.INSTANCE.getMappedOptions().toList();
String pkgName = String.join(File.separator, new CasedString(StringCase.DOT, packageName).getSegments());
File file = new File(new File(new File(destDir), pkgName), className + ".java");
@@ -159,17 +147,18 @@ public static void main(final String[] args) throws IOException {
String line = iter.next();
switch (line.trim()) {
case "${static}":
- for (Map.Entry entry : AntOption.getRenameMap().entrySet()) {
+ for (Map.Entry, ?> entry : AntOptionCollection.getRenameMap().entrySet()) {
writer.append(format(" xlateName.put(\"%s\", \"%s\");%n", entry.getKey(), entry.getValue()));
}
- for (Option option : AntOption.getFilteredOptions()) {
+
+ for (Option option : AntOptionCollection.INSTANCE.getUnsupportedOptions()
+ .getOptions()) {
writer.append(format(" unsupportedArgs.add(\"%s\");%n", argsKey(option)));
}
- for (AntOption option : options) {
- if (option.isDeprecated()) {
- writer.append(format(" deprecatedArgs.put(\"%s\", \"%s\");%n", argsKey(option.getOption()),
- format("Use of deprecated option '%s'. %s", option.getName(), option.getDeprecated())));
- }
+
+ for (AntOption option : AntOptionCollection.INSTANCE.getMappedOptions().filter(AntOption::isDeprecated).toList()) {
+ writer.append(format(" deprecatedArgs.put(\"%s\", \"%s\");%n", argsKey(option.getOption()),
+ format("Use of deprecated option '%s'. %s", option.getName(), option.getDeprecated())));
}
break;
case "${methods}":
@@ -190,7 +179,7 @@ public static void main(final String[] args) throws IOException {
case "${classes}":
customClasses.flush();
customClasses.close();
- writer.write(bos.toString());
+ writer.write(bos.toString(StandardCharsets.UTF_8));
break;
case "${commonArgs}":
try (InputStream argsTpl = MavenGenerator.class.getResourceAsStream("/Args.tpl")) {
@@ -209,23 +198,26 @@ public static void main(final String[] args) throws IOException {
}
private static void writeMethods(final FileWriter writer, final List options, final Writer customClasses) throws IOException {
- for (AntOption option : options) {
+ for (AntOption antOption : options) {
- if (option.isAttribute()) {
- writer.append(option.getComment(true));
- writer.append(format(" public void %s {%n%s%n }%n%n", option.getAttributeFunctionName(), getAttributeBody(option)));
+ if (antOption.isAttribute()) {
+ writer.append(getComment(antOption, true));
+ if (antOption.isDeprecated()) {
+ writer.append(" @Deprecated\n");
+ }
+ writer.append(format(" public void %s {%n%s%n }%n%n", getAttributeFunctionName(antOption), getAttributeBody(antOption)));
} else {
- customClasses.append(option.getComment(false));
+ customClasses.append(getComment(antOption, false));
customClasses.append(format(" public %1$s create%1$s() {%n return new %1$s();%n }%n%n",
- WordUtils.capitalize(option.getName())));
- customClasses.append(getElementClass(option));
+ antOption.getCasedName().toCase(StringCase.CAMEL)));
+ customClasses.append(getElementClass(antOption));
}
}
}
private static String getAttributeBody(final AntOption option) {
- return option.hasArg() ? format(" setArg(%s, %s);%n", option.keyValue(), option.getName())
- : format(" if (%1$s) { setArg(%2$s, null); } else { removeArg(%2$s); }", option.getName(), option.keyValue());
+ return option.hasArg() ? format(" setArg(\"%s\", %s);%n", option.keyValue(), option.getName())
+ : format(" if (%1$s) { setArg(\"%2$s\", null); } else { removeArg(\"%2$s\"); }", option.getName(), option.keyValue());
}
private static String getElementClass(final AntOption option) {
@@ -239,8 +231,8 @@ public class %1$s {
StringBuilder result = new StringBuilder(format(elementConstructor, funcName));
Set implementedOptions = new HashSet<>();
implementedOptions.add(option);
- option.convertedFrom().stream().filter(o -> !AntOption.getUnsupportedOptions().contains(o)).forEach(opt -> implementedOptions.add(new AntOption(opt)));
- implementedOptions.forEach(o -> result.append(GENERATE_TYPE_MAP.get(o.getArgType()).getPattern(option, o)));
+ implementedOptions.addAll(option.convertedFrom());
+ implementedOptions.forEach(antOption -> result.append(getGenerateType(antOption).getMethod(antOption)));
result.append(format(" }%n"));
return result.toString();
@@ -254,11 +246,12 @@ public static class GenerateType {
this.innerClass = innerClass;
}
- protected String getMethodFormat(final AntOption antOption) {
+ public String getMethod(final AntOption antOption) {
+ String variableName = WordUtils.uncapitalize(antOption.getArgName());
return String.format("""
- public void addConfigured%1$s(%1$s %%2$s) {
- addArg(%%1$s, %%2$s.value);
- }%n""", innerClass);
+ public void addConfigured%1$s(%1$s %2$s) {
+ addArg("%3$s", %2$s.value);
+ }%n""", innerClass, variableName, antOption.keyValue());
}
public String getPattern(final AntOption delegateOption, final AntOption antOption) {
@@ -266,10 +259,71 @@ public String getPattern(final AntOption delegateOption, final AntOption antOpti
String fmt = "";
return format(fmt, delegateOption.getName(), antOption.hasArg() ? antOption.getArgName() : "true");
} else {
- return format(getMethodFormat(antOption), antOption.keyValue(),
- WordUtils.uncapitalize(antOption.getArgName()));
+ String fmt = """
+
+ <%1$s>
+ <%2$s>%3$s%2$s>
+ %1$s>
+
+ """;
+ return format(fmt, delegateOption.getName(), innerClass, antOption.getArgName());
+ }
+ }
+ }
+
+ /**
+ * Get the method comment for this option.
+ *
+ * @param addParam if {@code true} the param annotation is added.
+ * @return the Comment block for the function.
+ */
+ private static String getComment(final AntOption antOption, final boolean addParam) {
+ StringBuilder sb = new StringBuilder();
+ String desc = antOption.getDescription();
+ if (desc == null) {
+ throw new IllegalStateException(format("Description for %s may not be null", antOption.getName()));
+ }
+ if (!desc.contains(".")) {
+ throw new IllegalStateException(format("First sentence of description for %s must end with a '.'", antOption.getName()));
+ }
+ if (addParam) {
+ String arg;
+ if (antOption.hasArg()) {
+ arg = desc.substring(desc.indexOf(" ") + 1, desc.indexOf(".") + 1);
+ arg = WordUtils.capitalize(arg.substring(0, 1)) + arg.substring(1);
+ } else {
+ arg = "The state";
}
+ if (antOption.getArgName() != null) {
+ Supplier sup = OptionCollection.getArgumentTypes().get(antOption.getArgName());
+ if (sup == null) {
+ throw new IllegalStateException(format("Argument type %s must be in OptionCollection.ARGUMENT_TYPES", antOption.getArgName()));
+ }
+ desc = format("%s Argument%s should be %s%s. (See Argument Types for clarification)", desc, antOption.hasArgs() ? "s" : "",
+ antOption.hasArgs() ? "" : "a ", antOption.getArgName());
+ }
+ sb.append(format(" /**%n * %s%n * @param %s %s%n", StringEscapeUtils.escapeHtml4(desc), antOption.getName(),
+ StringEscapeUtils.escapeHtml4(arg)));
+ } else {
+ sb.append(format(" /**%n * %s%n", StringEscapeUtils.escapeHtml4(desc)));
}
+ if (antOption.isDeprecated()) {
+ sb.append(format(" * @deprecated %s%n", StringEscapeUtils.escapeHtml4(antOption.getDeprecated())));
+ }
+ return sb.append(format(" */%n")).toString();
+ }
+
+ /**
+ * Get the signature of the attribute function.
+ *
+ * @return the signature of the attribute function.
+ */
+ public static String getAttributeFunctionName(final AntOption antOption) {
+ return "set" +
+ WordUtils.capitalize(antOption.getName()) +
+ (antOption.hasArg() ? "(String " : "(boolean ") +
+ antOption.getName() +
+ ")";
}
}
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/tools/MavenGenerator.java b/apache-rat-tools/src/main/java/org/apache/rat/tools/MavenGenerator.java
index 7c2aea91b..6d12c7bfd 100644
--- a/apache-rat-tools/src/main/java/org/apache/rat/tools/MavenGenerator.java
+++ b/apache-rat-tools/src/main/java/org/apache/rat/tools/MavenGenerator.java
@@ -24,7 +24,6 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
-import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
@@ -36,6 +35,7 @@
import org.apache.commons.text.WordUtils;
import org.apache.rat.OptionCollection;
import org.apache.rat.documentation.options.MavenOption;
+import org.apache.rat.documentation.options.MavenOptionCollection;
import org.apache.rat.utils.CasedString;
import org.apache.rat.utils.CasedString.StringCase;
@@ -74,7 +74,6 @@ public static void main(final String[] args) throws IOException {
String packageName = args[0];
String className = args[1];
String destDir = args[2];
- List options = MavenOption.getMavenOptions();
String pkgName = String.join(File.separator, new CasedString(StringCase.DOT, packageName).getSegments());
File file = new File(new File(new File(destDir), pkgName), className + ".java");
System.out.println("Creating " + file);
@@ -89,21 +88,19 @@ public static void main(final String[] args) throws IOException {
String line = iter.next();
switch (line.trim()) {
case "${static}":
- for (Map.Entry entry : MavenOption.getRenameMap().entrySet()) {
+ for (Map.Entry, ?> entry : MavenOptionCollection.getRenameMap().entrySet()) {
writer.append(format(" xlateName.put(\"%s\", \"%s\");%n", entry.getKey(), entry.getValue()));
}
- for (Option option : MavenOption.getFilteredOptions()) {
+ for (Option option : MavenOptionCollection.INSTANCE.getUnsupportedOptions().getOptions()) {
writer.append(format(" unsupportedArgs.add(\"%s\");%n", argsKey(option)));
}
- for (MavenOption option : options) {
- if (option.isDeprecated()) {
- writer.append(format(" deprecatedArgs.put(\"%s\", \"%s\");%n", argsKey(option.getOption()),
- format("Use of deprecated option '%s'. %s", option.getName(), option.getDeprecated())));
- }
+ for (MavenOption option : MavenOptionCollection.INSTANCE.getMappedOptions().filter(MavenOption::isDeprecated).toList()) {
+ writer.append(format(" deprecatedArgs.put(\"%s\", \"%s\");%n", argsKey(option.getOption()),
+ format("Use of deprecated option '%s'. %s", option.getName(), option.getDeprecated())));
}
break;
case "${methods}":
- writeMethods(writer, options);
+ writeMethods(writer);
break;
case "${package}":
writer.append(format("package %s;%n", packageName));
@@ -165,14 +162,14 @@ private static String getComment(final MavenOption option) {
return sb.append(format(" */%n")).toString();
}
- private static void writeMethods(final FileWriter writer, final List options) throws IOException {
- for (MavenOption option : options) {
+ private static void writeMethods(final FileWriter writer) throws IOException {
+ for (MavenOption option : MavenOptionCollection.INSTANCE.getMappedOptions().toList()) {
writer.append(getComment(option))
.append(option.getMethodSignature(" ", option.hasArgs())).append(" {").append(System.lineSeparator())
.append(getBody(option))
.append(" }").append(System.lineSeparator());
if (option.hasArgs()) {
- // create multi argument method
+ // create single argument method
writer.append(getComment(option))
.append(option.getMethodSignature(" ", false)).append(" {").append(System.lineSeparator())
.append(getBody(option))
@@ -183,10 +180,10 @@ private static void writeMethods(final FileWriter writer, final List filter = o -> o.hasLongOpt() && (!o.isDeprecated() || includeDeprecated);
@@ -139,20 +142,25 @@ public static void main(final String[] args) throws IOException, ParseException
} else if (showAnt) {
descriptionFunction = o -> {
StringBuilder desc = new StringBuilder();
- AntOption antOption = new AntOption(o);
- if (antOption.isDeprecated()) {
- desc.append("[").append(antOption.getDeprecated()).append("] ");
- }
- return desc.append(StringUtils.defaultIfEmpty(antOption.getDescription(), "")).toString();
+ antCollection.getMappedOption(o).ifPresent(
+ antOption -> {
+ if (antOption.isDeprecated()) {
+ desc.append("[").append(antOption.getDeprecated()).append("] ");
+ }
+ desc.append(StringUtils.defaultIfEmpty(antOption.getDescription(), ""));
+ });
+ return desc.toString();
};
} else {
descriptionFunction = o -> {
StringBuilder desc = new StringBuilder();
- MavenOption mavenOption = new MavenOption(o);
- if (mavenOption.isDeprecated()) {
- desc.append("[").append(mavenOption.getDeprecated()).append("] ");
- }
- return desc.append(StringUtils.defaultIfEmpty(mavenOption.getDescription(), "")).toString();
+ mavenCollection.getMappedOption(o).ifPresent(mavenOption -> {
+ if (mavenOption.isDeprecated()) {
+ desc.append("[").append(mavenOption.getDeprecated()).append("] ");
+ }
+ desc.append(StringUtils.defaultIfEmpty(mavenOption.getDescription(), ""));
+ });
+ return desc.toString();
};
}
@@ -169,6 +177,9 @@ public static void main(final String[] args) throws IOException, ParseException
private static List fillColumns(final List columns, final Option option, final boolean addCLI, final boolean showMaven,
final boolean showAnt, final Function
descriptionFunction) {
+ AntOptionCollection antCollection = AntOptionCollection.INSTANCE;
+ MavenOptionCollection mavenCollection = MavenOptionCollection.INSTANCE;
+
if (addCLI) {
if (option.hasLongOpt()) {
columns.add("--" + option.getLongOpt());
@@ -177,10 +188,12 @@ private static List fillColumns(final List columns, final Option
}
}
if (showAnt) {
- columns.add(new AntOption(option).getExample());
+ antCollection.getMappedOption(option).ifPresentOrElse(antOption -> columns.add(antOption.getExample()),
+ () -> columns.add(" "));
}
if (showMaven) {
- columns.add(new MavenOption(option).getExample());
+ mavenCollection.getMappedOption(option).ifPresentOrElse(mavenOption -> columns.add(mavenOption.getExample()),
+ () -> columns.add(" "));
}
columns.add(descriptionFunction.apply(option));
diff --git a/apache-rat-tools/src/test/java/org/apache/rat/documentation/options/MavenOptionTest.java b/apache-rat-tools/src/test/java/org/apache/rat/documentation/options/MavenOptionTest.java
index 70d12f846..5043f464c 100644
--- a/apache-rat-tools/src/test/java/org/apache/rat/documentation/options/MavenOptionTest.java
+++ b/apache-rat-tools/src/test/java/org/apache/rat/documentation/options/MavenOptionTest.java
@@ -30,9 +30,11 @@ public class MavenOptionTest {
public void getDeprecatedTest() {
for (Option option : Arg.getOptions().getOptions()) {
if (option.isDeprecated()) {
- MavenOption mavenOption = new MavenOption(option);
- String deprecated = mavenOption.getDeprecated();
- TextUtils.assertPatternNotInTarget("\\-\\- ", deprecated);
+ MavenOptionCollection.INSTANCE.getMappedOption(option).ifPresent( mavenOption -> {
+ String deprecated = mavenOption.getDeprecated();
+
+ TextUtils.assertPatternNotInTarget("\\-\\- ", deprecated);
+ });
}
}
}
From e49355355a14d10660487ec217973ed9e91aaf23 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Mon, 27 Apr 2026 16:35:18 +0100
Subject: [PATCH 10/11] Added AntOptionCollection.java
---
.../options/AntOptionCollection.java | 292 ++++++++++++++++++
1 file changed, 292 insertions(+)
create mode 100644 apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AntOptionCollection.java
diff --git a/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AntOptionCollection.java b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AntOptionCollection.java
new file mode 100644
index 000000000..728e245a9
--- /dev/null
+++ b/apache-rat-tools/src/main/java/org/apache/rat/documentation/options/AntOptionCollection.java
@@ -0,0 +1,292 @@
+/*
+ * 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
+ *
+ * https://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.documentation.options;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+
+import org.apache.commons.cli.Option;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.WordUtils;
+import org.apache.rat.OptionCollectionParser;
+import org.apache.rat.commandline.Arg;
+import org.apache.rat.ui.ArgumentTracker;
+import org.apache.rat.ui.UIOptionCollection;
+import org.apache.rat.utils.CasedString;
+
+import static java.lang.String.format;
+
+/**
+ * The collection of MavenOptions equivalent to the CLI options
+ * with any unsupported options removed.
+ */
+public final class AntOptionCollection extends UIOptionCollection {
+ /** mapping of standard name to non-conflicting name. */
+ private static final Map RENAME_MAP;
+
+ /** Attributes that are required for example data. */
+ private static final Map> REQUIRED_ATTRIBUTES = new HashMap<>();
+ /** The list of data types that are specified as XML attributes in ant build.xml documents */
+ private static final List> ATTRIBUTE_TYPES = new ArrayList<>();
+
+ /** The map of option name conversioins */
+ private final Map
conversionMap;
+
+ static {
+ RENAME_MAP = new HashMap<>();
+ RENAME_MAP.put("addLicense", "add-license");
+
+ Map attributes = new HashMap<>();
+ attributes.put("editLicense", "true");
+ REQUIRED_ATTRIBUTES.put("copyright", attributes);
+ REQUIRED_ATTRIBUTES.put("editCopyright", attributes);
+ REQUIRED_ATTRIBUTES.put("force", attributes);
+ REQUIRED_ATTRIBUTES.put("editOverwrite", attributes);
+
+ // types that are specified as XML attributes in Ant.
+ ATTRIBUTE_TYPES.add(String.class);
+ ATTRIBUTE_TYPES.add(String[].class);
+ ATTRIBUTE_TYPES.add(Integer.class);
+ ATTRIBUTE_TYPES.add(Long.class);
+ ATTRIBUTE_TYPES.add(File.class);
+
+ }
+
+ public static Map getRenameMap() {
+ return new TreeMap<>(RENAME_MAP);
+ }
+
+ /** The instance of the MavenOptionCollection */
+ public static final AntOptionCollection INSTANCE = new Builder().build();
+
+ /**
+ * Create an Instance.
+ */
+ private AntOptionCollection(final Builder builder) {
+ super(builder);
+ conversionMap = builder.conversions;
+ }
+
+ public Set convertedFrom(final AntOption antOption) {
+ return conversionMap.entrySet().stream().filter(e -> e.getValue().equals(antOption.getOption()))
+ .map(e -> getMappedOption(e.getKey()))
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect(Collectors.toSet());
+ }
+
+ /**
+ * If this option is converted to another option return that option otherwise
+ * return this option.
+ * @return the converted option.
+ */
+ public AntOption getActualAntOption(final AntOption antOption) {
+ Option opt = conversionMap.get(antOption.getOption());
+ return opt == null ? antOption : getMappedOption(opt).get();
+ }
+
+ public boolean isAttribute(final AntOption antOption) {
+ Option opt = antOption.getOption();
+ return (!opt.hasArg() || opt.getArgs() == 1) && convertedFrom(antOption).isEmpty() &&
+ ATTRIBUTE_TYPES.contains(opt.getType());
+ }
+
+ public Map getRequiredAttributes(final String name) {
+ return REQUIRED_ATTRIBUTES.get(name);
+ }
+
+ BuildType buildType(final OptionCollectionParser.ArgumentType type) {
+ return switch (type) {
+ case FILE, DIRORARCHIVE -> new BuildType("filename") {
+ @Override
+ protected String getMethodFormat(final AntOption antOption) {
+ return " \n";
+ }
+ };
+ case NONE -> new BuildType("");
+ case COUNTERPATTERN -> new BuildType("cntr");
+ case EXPRESSION -> new BuildType("expr");
+ case STANDARDCOLLECTION -> new BuildType("std");
+ case LICENSEID, FAMILYID -> new BuildType("lst");
+ default -> new BuildType(type.getDisplayName()) {
+ protected String getMethodFormat(final AntOption antOption) {
+ return String.format("<%1$s>%%s%1$s>%n", WordUtils.uncapitalize(antOption.getArgName()));
+ }
+ };
+ };
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Provides a new name for an option if it is renamed in the collection.
+ * @param name the option name.
+ * @return the collection name, may be the same as the option name.
+ */
+ static String rename(final String name) {
+ return StringUtils.defaultIfEmpty(RENAME_MAP.get(name), name);
+ }
+
+ /**
+ * Creates the name for the option based on rules for conversion of CLI option names.
+ * @param option the standard option.
+ * @return the new Option name as a CasedString.
+ */
+ static CasedString createName(final Option option) {
+ List 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.PASCAL);
+ }
+
+ /**
+ * The Builder for the MavenOptionCollection.
+ */
+ public static final class Builder extends UIOptionCollection.Builder {
+ /** convert key to value type when generating code */
+ private final Map
conversions = new HashMap<>();
+
+ private Builder() {
+ super();
+ Arg.getOptions().getOptions()
+ .stream().filter(o -> Objects.isNull(o.getLongOpt()))
+ .forEach(this::unsupported);
+ unsupported(Arg.LOG_LEVEL)
+ .unsupported(Arg.DIR)
+ .unsupported(Arg.SOURCE)
+ .unsupported(Arg.HELP_LICENSES)
+ .mapper((collection, option) -> new AntOption(collection, option))
+
+ // conversions
+ .convert(Arg.LICENSES_APPROVED_FILE, Arg.LICENSES_APPROVED)
+ .convert(Arg.LICENSES_DENIED_FILE, Arg.LICENSES_DENIED)
+ .convert(Arg.FAMILIES_APPROVED_FILE, Arg.FAMILIES_APPROVED)
+ .convert(Arg.FAMILIES_DENIED_FILE, Arg.FAMILIES_DENIED)
+ .convert(Arg.INCLUDE_FILE, Arg.INCLUDE)
+ .convert(Arg.INCLUDE_STD, Arg.INCLUDE)
+ .convert(Arg.EXCLUDE_FILE, Arg.EXCLUDE)
+ .convert(Arg.EXCLUDE_STD, Arg.EXCLUDE);
+ }
+
+ public AntOptionCollection build() {
+ return new AntOptionCollection(this);
+ }
+
+ public Builder convert(final Arg from, final Arg to) {
+ Option mapTo = to.option();
+ for (Option option : from.group().getOptions()) {
+ if (!option.equals(mapTo) && !option.isDeprecated()) {
+ conversions.put(option, mapTo);
+ }
+ }
+ return self();
+ }
+ }
+
+ /**
+ * A mapping of data type of XML format.
+ */
+ public static class BuildType {
+ /**
+ * The configuration tag for this build type
+ */
+ private final String tag;
+ /**
+ * If True adds the tag as the test extension
+ */
+ private final boolean addExt;
+
+ /**
+ * The constructor for the build type.
+ *
+ * @param tag the XML tag for this data type.
+ */
+ BuildType(final String tag) {
+ this.tag = tag;
+ this.addExt = StringUtils.isNotEmpty(tag);
+ }
+
+ /**
+ * Returns the format used when multiple arguments are expected by an Ant option.
+ *
+ * @param antOption the Ant option to check.
+ * @return the format used for multiple arguments.
+ */
+ protected String getMultipleFormat(final AntOption antOption) {
+ return String.format("<%1$s>%%s%1$s>%n", tag);
+ }
+
+ /**
+ * Gets the method based on how many arguments an Ant option requires.
+ *
+ * @param antOption the Ant option to check.
+ * @return the method format for the option.
+ */
+ protected String getMethodFormat(final AntOption antOption) {
+ return antOption.hasArgs() ? getMultipleFormat(antOption) : String.format("<%1$s>%%s%1$s>%n", tag);
+ }
+
+ /**
+ * Gets a string comprising the Ant XML pattern for this data type and the number of arguments expected by the Ant option.
+ *
+ * @param delegateOption the Ant option that the call is delegated to.
+ * @param antOption the actual ant option.
+ * @param data the data for the actual ant option.
+ * @return the Ant XML pattern for this data type.
+ */
+ public String getXml(final AntOption delegateOption, final AntOption antOption, final String data) {
+ String fmt = getMethodFormat(antOption);
+ String value = data == null ? WordUtils.uncapitalize(antOption.getArgName()) : data;
+ String inner = format(fmt, value);
+ return format("<%1$s>%2$s%1$s>%n", delegateOption.getName(), inner);
+ }
+
+ public String getXml(final AntOption antOption, final String data) {
+ AntOption delegateOption = antOption.getActualAntOption();
+ if (delegateOption.isAttribute()) {
+ return "";
+ } else {
+ return format(getMethodFormat(antOption), data);
+ }
+ }
+
+
+ public String testName(final AntOption antOption) {
+ return addExt ? format("%s_%s", antOption.getName(), antOption.getArgName()) : antOption.getName();
+ }
+ }
+}
From 5780186cafddbe422e4d75278c91f840f8ea30b2 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Mon, 27 Apr 2026 16:58:40 +0100
Subject: [PATCH 11/11] updated Arg documentation
---
.../java/org/apache/rat/commandline/Arg.java | 33 ++++++++++++++++---
1 file changed, 28 insertions(+), 5 deletions(-)
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 c7888b47d..f46551bfe 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
@@ -58,10 +58,16 @@
import static java.lang.String.format;
/**
- * An enumeration of options.
- *
- * Each Arg contains an OptionGroup that contains the individual options that all resolve to the same option.
- * This allows us to deprecate options as we move forward in development.
+ * An enumeration of options that are recommended across all UIs. A UI may not implement some options if they are unsupportable
+ * within the UI.
+ * Each Arg contains:
+ *
+ *
An OptionGroup that contains the individual options that all resolve to the same option.
+ * This allows us to deprecate options as we move forward in development.
+ *
A {@code BiConsumer} that defines the process to configure the option in
+ * the {@code ArgumentContext.configuration}.
+ *
+ *
*/
public enum Arg {
///////////////////////// EDIT OPTIONS
@@ -680,7 +686,7 @@ public enum Arg {
private final OptionGroup group;
/**
- * The apply the option to update the state of the context.configuration.
+ * The BiConsumer to apply the option to update the state of the context.configuration.
*/
private final BiConsumer process;
@@ -694,6 +700,11 @@ public enum Arg {
this.process = process;
}
+ /**
+ * Executes the process associated with this Arg if the collection has an Option from this group selected.
+ * @param context the ArgumentContext that is being processed.
+ * @param optionCollection the OptionCollection that is available.
+ */
private void execute(final ArgumentContext context, final UIOptionCollection> optionCollection) {
optionCollection.getSelected(this)
.ifPresent(selected -> this.process.accept(context, selected));
@@ -784,6 +795,12 @@ private static void processEditArgs(final ArgumentContext context, final UIOptio
});
}
+ /**
+ * Gets the list of Strings that are arguments for the option.
+ * @param context the ArgumentContext containing the command line.
+ * @param selected the selected option.
+ * @return the list of Strings that are aguments.
+ */
private static List processArrayArg(final ArgumentContext context, final Option selected) {
try {
return Arrays.asList(context.getCommandLine().getParsedOptionValue(selected));
@@ -792,6 +809,12 @@ private static List processArrayArg(final ArgumentContext context, final
}
}
+ /**
+ * parses lines with comma separated tokens from a file and returns the entire collection of tokens as a list of strings.
+ * @param context the Argument context that provides the command line.
+ * @param selected the selected option.
+ * @return the list of strings parsed from the file.
+ */
private static List processArrayFile(final ArgumentContext context, final Option selected) {
List result = new ArrayList<>();
try {