1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.munkei;
21
22 import java.io.PrintStream;
23 import java.lang.reflect.Field;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import com.munkei.exception.ArgumentParsingException;
30 import com.munkei.exception.NoSuchOptionException;
31
32
33
34
35
36
37
38 public class JArgP {
39
40
41
42
43
44
45
46
47 protected static String bold(String string) {
48 boolean ansi = true;
49 if (ansi) {
50 return "\033[1m" + string + "\033[22m";
51 }
52
53 return string;
54 }
55
56
57
58
59
60
61
62
63 protected static String underline(String string) {
64 boolean ansi = true;
65 if (ansi) {
66 return "\033[4m" + string + "\033[24m";
67 }
68
69 return string;
70 }
71
72 private List<Option> options;
73
74 private String usageHeader;
75
76
77
78
79
80
81
82
83 public JArgP(Object subject)
84 throws NullPointerException {
85 if (subject == null) {
86 throw new NullPointerException("Subject may not be null");
87 }
88
89 options = new ArrayList<>();
90
91 for (Field field : subject.getClass().getFields()) {
92 if (field.isAnnotationPresent(CommandLineOption.class)) {
93 options.add(new Option(subject, field));
94 }
95 }
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 public List<String> parse(String[] args)
115 throws NullPointerException,
116 NoSuchOptionException,
117 ArgumentParsingException {
118 if (args == null) {
119 throw new NullPointerException("Arguments may not be null");
120 }
121
122 List<String> remaining = new ArrayList<>();
123
124 Iterator<String> it = Arrays.asList(args).iterator();
125 while (it.hasNext()) {
126 String arg = it.next();
127
128
129 if (arg.equals("--")) {
130 while (it.hasNext()) {
131 remaining.add(it.next());
132 }
133 break;
134 }
135
136
137 if (arg.startsWith("--")) {
138 set(arg.substring(2), it);
139 continue;
140 }
141
142
143 if (arg.startsWith("-")) {
144 char[] chars = new char[arg.length() - 1];
145 arg.getChars(1, arg.length(), chars, 0);
146 for (char c : chars) {
147 set(Character.toString(c), it);
148 }
149
150 continue;
151 }
152
153
154 remaining.add(arg);
155 }
156
157
158 return remaining;
159 }
160
161
162
163
164
165
166
167
168 public void setUsageHeader(String usageHeader) {
169 this.usageHeader = usageHeader;
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183
184 public void printUsage(PrintStream output)
185 throws NullPointerException {
186 if (output == null) {
187 throw new NullPointerException("Output stream may not be null");
188 }
189
190
191 if (usageHeader != null) {
192 output.println(usageHeader);
193 output.println();
194 }
195
196 if (!options.isEmpty()) {
197 output.println(bold("Options"));
198 output.println();
199 }
200
201 for (Option option : options) {
202
203 List<String> names = new ArrayList<>(option.getNames());
204
205 if (option.getCommandLineOption().pattern() != null
206 && !option.getCommandLineOption().pattern().isEmpty()) {
207 names.add("/" + option.getCommandLineOption().pattern() + "/");
208 }
209
210 for (String name : names) {
211 output.print(" ");
212 output.print(bold(((name.length() == 1) ? "-" : "--") + name));
213 if (option.takesValue()) {
214 output.print(" ");
215 output.print(
216 underline(
217 (option.getCommandLineOption().placeholder() == null
218 || option.getCommandLineOption().placeholder().isEmpty())
219 ? "VALUE"
220 : option.getCommandLineOption().placeholder()
221 )
222 );
223 }
224 output.println();
225 }
226
227 if (option.getCommandLineOption().description() != null
228 && !option.getCommandLineOption().description().isEmpty()) {
229 output.println();
230 output.print(" ");
231 output.println(option.getCommandLineOption().description());
232 }
233
234 if (option.getCommandLineOption().defaultValue() != null
235 && !option.getCommandLineOption().defaultValue().isEmpty()) {
236 output.println();
237 output.print(" Default: ");
238 output.println(option.getCommandLineOption().defaultValue());
239 }
240
241 output.println();
242 }
243 }
244
245
246
247
248 public void printUsage() {
249 printUsage(System.out);
250 }
251
252 private void set(String name,
253 Iterator<String> it)
254 throws NoSuchOptionException,
255 ArgumentParsingException {
256 Option option = optionForName(name);
257 option.set(name, it);
258 }
259
260 private Option optionForName(String name)
261 throws NoSuchOptionException {
262 for (Option option : options) {
263 if (option.hasName(name)) {
264 return option;
265 }
266 }
267
268 throw new NoSuchOptionException(name);
269 }
270
271 }