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