1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.tools;
20
21 import java.io.File;
22 import java.io.FileWriter;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.nio.charset.StandardCharsets;
27 import java.util.Map;
28 import java.util.Optional;
29
30 import org.apache.commons.cli.Option;
31 import org.apache.commons.io.IOUtils;
32 import org.apache.commons.io.LineIterator;
33 import org.apache.commons.lang3.StringUtils;
34 import org.apache.commons.text.StringEscapeUtils;
35 import org.apache.commons.text.WordUtils;
36 import org.apache.rat.OptionCollection;
37 import org.apache.rat.documentation.options.MavenOption;
38 import org.apache.rat.documentation.options.MavenOptionCollection;
39 import org.apache.rat.utils.CasedString;
40 import org.apache.rat.utils.CasedString.StringCase;
41
42 import static java.lang.String.format;
43
44
45
46
47 public final class MavenGenerator {
48
49 private MavenGenerator() {
50 }
51
52 private static String argsKey(final Option option) {
53 return StringUtils.defaultIfEmpty(option.getLongOpt(), option.getOpt());
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67
68 public static void main(final String[] args) throws IOException {
69 if (args == null || args.length < 3) {
70 System.err.println("At least three arguments are required: package, simple class name, target directory.");
71 return;
72 }
73
74 String packageName = args[0];
75 String className = args[1];
76 String destDir = args[2];
77
78 final MavenOptionCollection mavenOptions = new MavenOptionCollection();
79
80 String pkgName = String.join(File.separator, new CasedString(StringCase.DOT, packageName).getSegments());
81 File file = new File(new File(new File(destDir), pkgName), className + ".java");
82 System.out.println("Creating " + file);
83 file.getParentFile().mkdirs();
84 try (InputStream template = MavenGenerator.class.getResourceAsStream("/Maven.tpl");
85 FileWriter writer = new FileWriter(file, StandardCharsets.UTF_8)) {
86 if (template == null) {
87 throw new RuntimeException("Template /Maven.tpl not found");
88 }
89 LineIterator iter = IOUtils.lineIterator(new InputStreamReader(template, StandardCharsets.UTF_8));
90 while (iter.hasNext()) {
91 String line = iter.next();
92 switch (line.trim()) {
93 case "${static}":
94 for (Map.Entry<?, ?> entry : MavenOptionCollection.getRenameMap().entrySet()) {
95 writer.append(format(" xlateName.put(\"%s\", \"%s\");%n", entry.getKey(), entry.getValue()));
96 }
97 for (Option option : mavenOptions.getUnsupportedOptions().getOptions()) {
98 writer.append(format(" unsupportedArgs.add(\"%s\");%n", argsKey(option)));
99 }
100 for (MavenOption option : mavenOptions.getMappedOptions().filter(MavenOption::isDeprecated).toList()) {
101 writer.append(format(" deprecatedArgs.put(\"%s\", \"%s\");%n", argsKey(option.getOption()),
102 format("Use of deprecated option '%s'. %s", option.getName(), option.getDeprecated())));
103 }
104 break;
105 case "${methods}":
106 writeMethods(mavenOptions, writer);
107 break;
108 case "${package}":
109 writer.append(format("package %s;%n", packageName));
110 break;
111 case "${constructor}":
112 writer.append(format("""
113 protected %s() {
114 setDeprecationReporter();
115 }%n""", className));
116 break;
117 case "${class}":
118 writer.append(format("public abstract class %s extends AbstractMojo {%n", className));
119 break;
120 case "${commonArgs}":
121 try (InputStream argsTpl = MavenGenerator.class.getResourceAsStream("/Args.tpl")) {
122 if (argsTpl == null) {
123 throw new RuntimeException("Args.tpl not found");
124 }
125 IOUtils.copy(argsTpl, writer, StandardCharsets.UTF_8);
126 }
127 break;
128 default:
129 writer.append(line).append(System.lineSeparator());
130 break;
131 }
132 }
133 }
134 }
135
136
137 static String getComment(final MavenOption option) {
138 String desc = option.getDescription();
139 if (desc == null) {
140 throw new IllegalStateException(format("Description for %s must not be null", option.getName()));
141 }
142 if (!desc.contains(".")) {
143 throw new IllegalStateException(format("First sentence of description for %s must end with a '.'", option.getName()));
144 }
145
146 String arg = getArgumentDescription(option, desc);
147
148 desc = appendArgumentTypeDescription(option, desc);
149
150 StringBuilder sb = new StringBuilder()
151 .append(format(" /**%n * %s%n * @param %s %s%n", StringEscapeUtils.escapeHtml4(desc),
152 option.getName(), StringEscapeUtils.escapeHtml4(arg)));
153 if (option.isDeprecated()) {
154 sb.append(format(" * @deprecated %s%n", StringEscapeUtils.escapeHtml4(option.getDeprecated())));
155 }
156 return sb.append(format(" */%n")).toString();
157 }
158
159
160 static String getArgumentDescription(final MavenOption option, final String desc) {
161 if (!option.hasArg()) {
162 return "The state";
163 }
164
165 String arg = desc.substring(desc.indexOf(" ") + 1, desc.indexOf(".") + 1);
166 return WordUtils.capitalize(arg.substring(0, 1)) + arg.substring(1);
167 }
168
169
170 static String appendArgumentTypeDescription(final MavenOption option, final String desc) {
171 if (!option.hasArg() || option.getArgName() == null) {
172 return desc;
173 }
174
175 Optional<OptionCollection.ArgumentType> type = OptionCollection.ArgumentType.forDisplayName(option.getArgName());
176 if (type.isPresent()) {
177 return format("%s Argument%s should be %s%s. (See Argument Types for clarification)",
178 desc,
179 option.hasArgs() ? "s" : "",
180 option.hasArgs() ? "" : "a ",
181 option.getArgName());
182 }
183
184 throw new IllegalStateException(
185 format("Argument type %s must be in OptionCollection.ArgumentType",
186 option.getArgName()));
187 }
188
189 private static void writeMethods(final MavenOptionCollection mavenOptions, final FileWriter writer) throws IOException {
190 for (MavenOption option : mavenOptions.getMappedOptions().toList()) {
191 writer.append(getComment(option))
192 .append(option.getMethodSignature(" ", option.hasArgs())).append(" {").append(System.lineSeparator())
193 .append(getBody(option))
194 .append(" }").append(System.lineSeparator());
195 if (option.hasArgs()) {
196
197 writer.append(getComment(option))
198 .append(option.getMethodSignature(" ", false)).append(" {").append(System.lineSeparator())
199 .append(getBody(option))
200 .append(" }").append(System.lineSeparator());
201 }
202 }
203 }
204
205 private static String getBody(final MavenOption option) {
206 if (option.hasArg()) {
207 return format(" %sArg(\"%s\", %s);%n", option.hasArgs() ? "add" : "set", option.keyValue(), option.getName());
208 } else {
209 return format(" if (%1$s) {%n setArg(\"%2$s\", null);%n" +
210 " } else {%n removeArg(\"%2$s\");%n }%n",
211 option.getName(), option.keyValue());
212 }
213 }
214 }