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.ByteArrayOutputStream;
22 import java.io.File;
23 import java.io.FileWriter;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.OutputStreamWriter;
28 import java.io.Writer;
29 import java.nio.charset.StandardCharsets;
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Locale;
34 import java.util.Map;
35 import java.util.function.Predicate;
36 import java.util.stream.Collectors;
37
38 import org.apache.commons.cli.Option;
39 import org.apache.commons.io.IOUtils;
40 import org.apache.commons.io.LineIterator;
41 import org.apache.commons.lang3.StringUtils;
42 import org.apache.commons.text.WordUtils;
43 import org.apache.rat.OptionCollection;
44 import org.apache.rat.commandline.Arg;
45 import org.apache.rat.utils.CasedString;
46 import org.apache.rat.utils.CasedString.StringCase;
47
48 import static java.lang.String.format;
49
50
51
52
53 public final class AntGenerator {
54
55
56
57
58 private static final List<Option> ANT_FILTER_LIST = new ArrayList<>();
59
60 static {
61 ANT_FILTER_LIST.addAll(Arg.LOG_LEVEL.group().getOptions());
62 ANT_FILTER_LIST.addAll(Arg.DIR.group().getOptions());
63 ANT_FILTER_LIST.add(OptionCollection.HELP);
64 }
65
66
67
68
69 private static final Predicate<Option> ANT_FILTER = option -> !(ANT_FILTER_LIST.contains(option) || option.getLongOpt() == null);
70
71
72 private static final Map<String, String> RENAME_MAP = new HashMap<>();
73
74 static {
75 RENAME_MAP.put("addLicense", "add-license");
76 }
77
78 private AntGenerator() { }
79
80
81
82
83
84 public static Predicate<Option> getFilter() {
85 return ANT_FILTER;
86 }
87
88
89
90
91
92
93
94
95
96
97
98 public static void main(final String[] args) throws IOException {
99 if (args == null || args.length < 3) {
100 System.err.println("At least three arguments are required: package, simple class name, target directory.");
101 return;
102 }
103
104 String packageName = args[0];
105 String className = args[1];
106 String destDir = args[2];
107
108 List<AntOption> options = Arg.getOptions().getOptions().stream().filter(ANT_FILTER).map(AntOption::new)
109 .collect(Collectors.toList());
110
111 String pkgName = String.join(File.separator, new CasedString(StringCase.DOT, packageName).getSegments());
112 File file = new File(new File(new File(destDir), pkgName), className + ".java");
113 file.getParentFile().mkdirs();
114 try (InputStream template = AntGenerator.class.getResourceAsStream("/Ant.tpl");
115 FileWriter writer = new FileWriter(file);
116 ByteArrayOutputStream bos = new ByteArrayOutputStream();
117 OutputStreamWriter customClasses = new OutputStreamWriter(bos)) {
118 if (template == null) {
119 throw new RuntimeException("Template /Ant.tpl not found");
120 }
121 LineIterator iter = IOUtils.lineIterator(new InputStreamReader(template, StandardCharsets.UTF_8));
122 while (iter.hasNext()) {
123 String line = iter.next();
124 switch (line.trim()) {
125 case "${static}":
126 for (Map.Entry<String, String> entry : RENAME_MAP.entrySet()) {
127 writer.append(format(" xlateName.put(\"%s\", \"%s\");%n", entry.getKey(), entry.getValue()));
128 }
129 for (Option option : ANT_FILTER_LIST) {
130 writer.append(format(" unsupportedArgs.add(\"%s\");%n", StringUtils.defaultIfEmpty(option.getLongOpt(), option.getOpt())));
131 }
132 break;
133 case "${methods}":
134 writeMethods(writer, options, customClasses);
135 break;
136 case "${package}":
137 writer.append(format("package %s;%n", packageName));
138 break;
139 case "${constructor}":
140 writer.append(format(" protected %s() {}%n", className));
141 break;
142 case "${class}":
143 writer.append(format("public abstract class %s extends Task {%n", className));
144 break;
145 case "${classes}":
146 customClasses.flush();
147 customClasses.close();
148 writer.write(bos.toString());
149 break;
150 case "${commonArgs}":
151 try (InputStream argsTpl = MavenGenerator.class.getResourceAsStream("/Args.tpl")) {
152 if (argsTpl == null) {
153 throw new RuntimeException("Args.tpl not found");
154 }
155 IOUtils.copy(argsTpl, writer, StandardCharsets.UTF_8);
156 }
157 break;
158 default:
159 writer.append(line).append(System.lineSeparator());
160 break;
161 }
162 }
163 }
164 }
165
166 private static void writeMethods(final FileWriter writer, final List<AntOption> options, final Writer customClasses) throws IOException {
167 for (AntOption option : options) {
168
169 if (option.isAttribute()) {
170 writer.append(option.getComment(true));
171 writer.append(format(" public void %s {%n%s%n }%n%n", option.getAttributeFunctionName(), getAttributeBody(option)));
172 }
173
174 if (option.isElement()) {
175 customClasses.append(option.getComment(false));
176 customClasses.append(format(" public %1$s create%1$s() {%n return new %1$s();%n }%n%n",
177 WordUtils.capitalize(option.getName())));
178 customClasses.append(getElementClass(option));
179 }
180 }
181 }
182
183 private static String getAttributeBody(final AntOption option) {
184 return option.hasArg() ? format(" setArg(%s, %s);%n", option.keyValue(), option.getName())
185 : format(" if (%1$s) { setArg(%2$s, null); } else { removeArg(%2$s); }", option.getName(), option.keyValue());
186 }
187
188 private static String getElementClass(final AntOption option) {
189 return format(" public class %1$s extends Child { %1$s() {super(%2$s);}}%n%n", WordUtils.capitalize(option.getName()),
190 option.keyValue());
191 }
192
193 static String createName(final Option option) {
194 String name = option.getLongOpt();
195 name = StringUtils.defaultIfEmpty(RENAME_MAP.get(name), name).toLowerCase(Locale.ROOT);
196 return new CasedString(StringCase.KEBAB, name).toCase(StringCase.CAMEL);
197 }
198 }