1 package jalview.bin.argparser;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.EnumSet;
7 import java.util.Locale;
8 import java.util.stream.Collectors;
12 HELP("h"), CALCULATION, MENUBAR, STATUS, SHOWOVERVIEW, ANNOTATIONS,
13 COLOUR, FEATURES, GROOVY, GROUPS, HEADLESS, JABAWS, ANNOTATION,
14 ANNOTATION2, DISPLAY, GUI, NEWS, SORTBYTREE, USAGESTATS, OPEN, OPENNEW,
15 PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC, VSESS, OUTPUT, OUTPUTTYPE,
16 SSANNOTATION, NOTEMPFAC, TEMPFAC, TEMPFAC_LABEL, TEMPFAC_DESC,
17 TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP, NOSTRUCTURE, STRUCTURE, IMAGE,
18 QUIT, CLOSE, DEBUG("d"), QUIET("q"), ARGFILE, INCREMENT, NPP("n++"),
19 SUBSTITUTIONS, INITSUBSTITUTIONS, NIL, SPLASH, SETARGFILE, UNSETARGFILE;
21 protected static enum Opt
23 BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES, BOOTSTRAP,
24 GLOB, NOACTION, ALLOWSUBSTITUTIONS, PRIVATE
29 HELP.setOptions("Display this help message", Opt.UNARY, Opt.BOOTSTRAP);
30 CALCULATION.setOptions(true, Opt.BOOLEAN); // default "true" implies only
31 // expecting "--nocalculation"
32 MENUBAR.setOptions(true, Opt.BOOLEAN);
33 STATUS.setOptions(true, Opt.BOOLEAN);
34 SHOWOVERVIEW.setOptions(Opt.UNARY, Opt.LINKED);
35 ANNOTATIONS.setOptions(Opt.STRING, Opt.LINKED);
36 COLOUR.setOptions(Opt.STRING, Opt.LINKED);
37 FEATURES.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
38 Opt.ALLOWSUBSTITUTIONS);
39 GROOVY.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
40 Opt.ALLOWSUBSTITUTIONS);
41 GROUPS.setOptions(Opt.STRING, Opt.LINKED);
42 HEADLESS.setOptions(Opt.UNARY, Opt.BOOTSTRAP);
43 JABAWS.setOptions(Opt.STRING);
44 ANNOTATION.setOptions(true, Opt.BOOLEAN, Opt.LINKED);
45 ANNOTATION2.setOptions(true, Opt.BOOLEAN, Opt.LINKED);
46 DISPLAY.setOptions(true, Opt.BOOLEAN);
47 GUI.setOptions(true, Opt.BOOLEAN);
48 NEWS.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
49 SPLASH.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
50 // expects a string value
51 SORTBYTREE.setOptions(true, Opt.BOOLEAN);
52 USAGESTATS.setOptions(true, Opt.BOOLEAN);
53 OPEN.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
54 Opt.ALLOWSUBSTITUTIONS);
55 OPENNEW.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
56 Opt.ALLOWSUBSTITUTIONS);
57 PROPS.setOptions(Opt.STRING, Opt.BOOTSTRAP);
58 QUESTIONNAIRE.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
59 SETPROP.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP);
60 TREE.setOptions(Opt.STRING);
62 VDOC.setOptions(Opt.UNARY);
63 VSESS.setOptions(Opt.UNARY);
65 OUTPUT.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
66 OUTPUTTYPE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
68 SSANNOTATION.setOptions(Opt.BOOLEAN, Opt.LINKED);
69 NOTEMPFAC.setOptions(Opt.UNARY, Opt.LINKED);
70 TEMPFAC.setOptions(Opt.STRING, Opt.LINKED);
71 TEMPFAC_LABEL.setOptions(Opt.STRING, Opt.LINKED);
72 TEMPFAC_DESC.setOptions(Opt.STRING, Opt.LINKED);
73 TEMPFAC_SHADING.setOptions(Opt.BOOLEAN, Opt.LINKED);
74 TITLE.setOptions(Opt.STRING, Opt.LINKED);
75 PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
76 Opt.ALLOWSUBSTITUTIONS);
77 NOSTRUCTURE.setOptions(Opt.UNARY, Opt.LINKED);
78 STRUCTURE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
79 Opt.ALLOWSUBSTITUTIONS);
80 WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED);
81 IMAGE.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
82 QUIT.setOptions(Opt.UNARY);
83 CLOSE.setOptions(Opt.UNARY, Opt.LINKED);
84 DEBUG.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
85 QUIET.setOptions(Opt.UNARY, Opt.MULTI, Opt.BOOTSTRAP);
86 ARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.GLOB,
87 Opt.ALLOWSUBSTITUTIONS);
88 INCREMENT.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
89 NPP.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
90 SUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION);
91 INITSUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION);
92 NIL.setOptions(Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.NOACTION);
93 SETARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
94 UNSETARGFILE.setOptions(Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
95 // Opt.BOOTSTRAP args are parsed (not linked with no SubVals so using a
96 // simplified parser, see jalview.bin.argparser.BootstrapArgs)
97 // before a full parse of arguments and so can be accessible at an earlier
98 // stage to (e.g.) set debug log level, provide a props file (that might set
99 // log level), run headlessly, read an argfile instead of other args.
102 private final String[] argNames;
104 private Opt[] argOptions;
106 private boolean defaultBoolValue = false;
108 private String description = null;
115 private Arg(String... names)
117 int length = (names == null || names.length == 0
118 || (names.length == 1 && names[0] == null)) ? 1
120 this.argNames = new String[length];
121 this.argNames[0] = this.getName();
123 System.arraycopy(names, 0, this.argNames, 1, names.length);
126 public String argString()
128 return argString(false);
131 public String negateArgString()
133 return argString(true);
136 private String argString(boolean negate)
138 StringBuilder sb = new StringBuilder(ArgParser.DOUBLEDASH);
139 if (negate && hasOption(Opt.BOOLEAN))
140 sb.append(ArgParser.NEGATESTRING);
141 sb.append(getName());
142 return sb.toString();
145 public String toLongString()
147 StringBuilder sb = new StringBuilder();
148 sb.append(this.getClass().getName()).append('.').append(this.name());
150 if (getNames().length > 0)
152 sb.append(String.join("\", \"", getNames()));
153 if (getNames().length > 0)
156 sb.append("\nOpt: ");
157 // map List<Opt> to List<String> for the String.join
158 List<String> optList = Arrays.asList(argOptions).stream()
159 .map(opt -> opt.name()).collect(Collectors.toList());
160 sb.append(String.join(", ", optList));
162 return sb.toString();
165 public String[] getNames()
170 public String getName()
172 return this.name().toLowerCase(Locale.ROOT).replace('_', '-');
176 public final String toString()
181 public boolean hasOption(Opt o)
183 if (argOptions == null)
185 for (Opt option : argOptions)
193 protected void setOptions(Opt... options)
195 setOptions("", false, options);
198 protected void setOptions(String desc, Opt... options)
200 setOptions(desc, false, options);
203 protected void setOptions(boolean defaultBoolValue, Opt... options)
205 setOptions("", defaultBoolValue, options);
208 protected void setOptions(String desc, boolean defaultBoolValue,
211 this.description = desc;
212 this.defaultBoolValue = defaultBoolValue;
213 this.argOptions = options;
216 protected boolean getDefaultBoolValue()
218 return defaultBoolValue;
221 private void setDescription(String d)
226 protected String getDescription()
231 public static String booleanArgString(Arg a)
233 StringBuilder sb = new StringBuilder(a.argString());
234 if (a.hasOption(Opt.BOOLEAN))
237 sb.append(a.negateArgString());
239 return sb.toString();
242 public static final String usage()
244 StringBuilder sb = new StringBuilder();
246 sb.append("Usage: jalview [args]");
247 sb.append(System.lineSeparator());
249 int maxArgLength = 0;
250 for (Arg a : EnumSet.allOf(Arg.class))
252 if (a.hasOption(Opt.PRIVATE))
254 StringBuilder argSb = new StringBuilder();
255 argSb.append(a.hasOption(Opt.BOOLEAN) ? booleanArgString(a)
257 if (a.hasOption(Opt.STRING))
258 argSb.append("=value");
259 if (argSb.length() > maxArgLength)
260 maxArgLength = argSb.length();
263 // might want to sort these
264 for (Arg a : EnumSet.allOf(Arg.class))
266 if (a.hasOption(Opt.PRIVATE))
268 StringBuilder argSb = new StringBuilder();
269 argSb.append(a.hasOption(Opt.BOOLEAN) ? booleanArgString(a)
271 if (a.hasOption(Opt.STRING))
272 argSb.append("=value");
273 sb.append(String.format("%-" + maxArgLength + "s - %s",
274 argSb.toString(), a.getDescription()));
276 List<String> options = new ArrayList<>();
278 if (a.hasOption(Opt.BOOLEAN))
280 options.add("default " + (a.getDefaultBoolValue() ? a.argString()
281 : a.negateArgString()));
284 if (a.hasOption(Opt.MULTI))
286 options.add("multiple");
289 if (a.hasOption(Opt.LINKED))
291 options.add("can be linked");
294 if (a.hasOption(Opt.GLOB))
296 options.add("allows file globs");
299 if (a.hasOption(Opt.ALLOWSUBSTITUTIONS))
301 options.add("allows substitutions");
304 if (options.size() > 0)
307 sb.append(String.join("; ", options));
310 sb.append(System.lineSeparator());
312 return sb.toString();