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.function.Supplier;
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 String pkgName = String.join(File.separator, new CasedString(StringCase.DOT, packageName).getSegments());
78 File file = new File(new File(new File(destDir), pkgName), className + ".java");
79 System.out.println("Creating " + file);
80 file.getParentFile().mkdirs();
81 try (InputStream template = MavenGenerator.class.getResourceAsStream("/Maven.tpl");
82 FileWriter writer = new FileWriter(file, StandardCharsets.UTF_8)) {
83 if (template == null) {
84 throw new RuntimeException("Template /Maven.tpl not found");
85 }
86 LineIterator iter = IOUtils.lineIterator(new InputStreamReader(template, StandardCharsets.UTF_8));
87 while (iter.hasNext()) {
88 String line = iter.next();
89 switch (line.trim()) {
90 case "${static}":
91 for (Map.Entry<?, ?> entry : MavenOptionCollection.getRenameMap().entrySet()) {
92 writer.append(format(" xlateName.put(\"%s\", \"%s\");%n", entry.getKey(), entry.getValue()));
93 }
94 for (Option option : MavenOptionCollection.INSTANCE.getUnsupportedOptions().getOptions()) {
95 writer.append(format(" unsupportedArgs.add(\"%s\");%n", argsKey(option)));
96 }
97 for (MavenOption option : MavenOptionCollection.INSTANCE.getMappedOptions().filter(MavenOption::isDeprecated).toList()) {
98 writer.append(format(" deprecatedArgs.put(\"%s\", \"%s\");%n", argsKey(option.getOption()),
99 format("Use of deprecated option '%s'. %s", option.getName(), option.getDeprecated())));
100 }
101 break;
102 case "${methods}":
103 writeMethods(writer);
104 break;
105 case "${package}":
106 writer.append(format("package %s;%n", packageName));
107 break;
108 case "${constructor}":
109 writer.append(format("""
110 protected %s() {
111 setDeprecationReporter();
112 }%n""", className));
113 break;
114 case "${class}":
115 writer.append(format("public abstract class %s extends AbstractMojo {%n", className));
116 break;
117 case "${commonArgs}":
118 try (InputStream argsTpl = MavenGenerator.class.getResourceAsStream("/Args.tpl")) {
119 if (argsTpl == null) {
120 throw new RuntimeException("Args.tpl not found");
121 }
122 IOUtils.copy(argsTpl, writer, StandardCharsets.UTF_8);
123 }
124 break;
125 default:
126 writer.append(line).append(System.lineSeparator());
127 break;
128 }
129 }
130 }
131 }
132
133 private static String getComment(final MavenOption option) {
134 String desc = option.getDescription();
135 if (desc == null) {
136 throw new IllegalStateException(format("Description for %s may not be null", option.getName()));
137 }
138 if (!desc.contains(".")) {
139 throw new IllegalStateException(format("First sentence of description for %s must end with a '.'", option.getName()));
140 }
141 String arg;
142 if (option.hasArg()) {
143 arg = desc.substring(desc.indexOf(" ") + 1, desc.indexOf(".") + 1);
144 arg = WordUtils.capitalize(arg.substring(0, 1)) + arg.substring(1);
145 } else {
146 arg = "The state";
147 }
148 if (option.hasArg() && option.getArgName() != null) {
149 Supplier<String> sup = OptionCollection.getArgumentTypes().get(option.getArgName());
150 if (sup == null) {
151 throw new IllegalStateException(format("Argument type %s must be in OptionCollection.ARGUMENT_TYPES", option.getArgName()));
152 }
153 desc = format("%s Argument%s should be %s%s. (See Argument Types for clarification)", desc, option.hasArgs() ? "s" : "",
154 option.hasArgs() ? "" : "a ", option.getArgName());
155 }
156 StringBuilder sb = new StringBuilder()
157 .append(format(" /**%n * %s%n * @param %s %s%n", StringEscapeUtils.escapeHtml4(desc),
158 option.getName(), StringEscapeUtils.escapeHtml4(arg)));
159 if (option.isDeprecated()) {
160 sb.append(format(" * @deprecated %s%n", StringEscapeUtils.escapeHtml4(option.getDeprecated())));
161 }
162 return sb.append(format(" */%n")).toString();
163 }
164
165 private static void writeMethods(final FileWriter writer) throws IOException {
166 for (MavenOption option : MavenOptionCollection.INSTANCE.getMappedOptions().toList()) {
167 writer.append(getComment(option))
168 .append(option.getMethodSignature(" ", option.hasArgs())).append(" {").append(System.lineSeparator())
169 .append(getBody(option))
170 .append(" }").append(System.lineSeparator());
171 if (option.hasArgs()) {
172
173 writer.append(getComment(option))
174 .append(option.getMethodSignature(" ", false)).append(" {").append(System.lineSeparator())
175 .append(getBody(option))
176 .append(" }").append(System.lineSeparator());
177 }
178 }
179 }
180
181 private static String getBody(final MavenOption option) {
182 if (option.hasArg()) {
183 return format(" %sArg(\"%s\", %s);%n", option.hasArgs() ? "add" : "set", option.keyValue(), option.getName());
184 } else {
185 return format(" if (%1$s) {%n setArg(\"%2$s\", null);%n" +
186 " } else {%n removeArg(\"%2$s\");%n }%n",
187 option.getName(), option.keyValue());
188 }
189 }
190 }