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, DISPLAY, GUI, NEWS,
14 SORTBYTREE, USAGESTATS, APPEND, OPEN, PROPS, QUESTIONNAIRE, SETPROP, TREE,
15 VDOC, VSESS, OUTPUT, OUTPUTTYPE, SSANNOTATIONS, NOTEMPFAC, TEMPFAC, TITLE,
16 PAEMATRIX, WRAP, NOSTRUCTURE, STRUCTURE, STRUCTUREVIEWER, IMAGE, QUIT,
17 CLOSE, DEBUG("d"), QUIET("q"), ARGFILE, INCREMENT, NPP("n++"),
18 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.BOOLEAN, 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 DISPLAY.setOptions(true, Opt.BOOLEAN);
45 GUI.setOptions(true, Opt.BOOLEAN);
46 NEWS.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
47 SPLASH.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
48 // expects a string value
49 SORTBYTREE.setOptions(true, Opt.BOOLEAN);
50 USAGESTATS.setOptions(true, Opt.BOOLEAN);
51 APPEND.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
52 Opt.ALLOWSUBSTITUTIONS);
53 OPEN.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
54 Opt.ALLOWSUBSTITUTIONS);
55 PROPS.setOptions(Opt.STRING, Opt.BOOTSTRAP);
56 QUESTIONNAIRE.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
57 SETPROP.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP);
58 TREE.setOptions(Opt.STRING);
60 VDOC.setOptions(Opt.UNARY);
61 VSESS.setOptions(Opt.UNARY);
63 OUTPUT.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
64 OUTPUTTYPE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
66 SSANNOTATIONS.setOptions(Opt.BOOLEAN, Opt.LINKED);
67 NOTEMPFAC.setOptions(Opt.UNARY, Opt.LINKED);
68 TEMPFAC.setOptions(Opt.STRING, Opt.LINKED);
69 TITLE.setOptions(Opt.STRING, Opt.LINKED);
70 PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
71 Opt.ALLOWSUBSTITUTIONS);
72 NOSTRUCTURE.setOptions(Opt.UNARY, Opt.LINKED);
73 STRUCTURE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
74 Opt.ALLOWSUBSTITUTIONS);
75 STRUCTUREVIEWER.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
76 WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED);
77 IMAGE.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
78 QUIT.setOptions(Opt.UNARY);
79 CLOSE.setOptions(Opt.UNARY, Opt.LINKED);
80 DEBUG.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
81 QUIET.setOptions(Opt.UNARY, Opt.MULTI, Opt.BOOTSTRAP);
82 ARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.GLOB,
83 Opt.ALLOWSUBSTITUTIONS);
84 INCREMENT.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
85 NPP.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
86 SUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION);
87 INITSUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION);
88 NIL.setOptions(Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.NOACTION);
89 SETARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
90 UNSETARGFILE.setOptions(Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
91 WEBSERVICEDISCOVERY.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
92 // Opt.BOOTSTRAP args are parsed (not linked with no SubVals so using a
93 // simplified parser, see jalview.bin.argparser.BootstrapArgs)
94 // before a full parse of arguments and so can be accessible at an earlier
95 // stage to (e.g.) set debug log level, provide a props file (that might set
96 // log level), run headlessly, read an argfile instead of other args.
99 private final String[] argNames;
101 private Opt[] argOptions;
103 private boolean defaultBoolValue = false;
105 private String description = null;
112 private Arg(String... names)
114 int length = (names == null || names.length == 0
115 || (names.length == 1 && names[0] == null)) ? 1
117 this.argNames = new String[length];
118 this.argNames[0] = this.getName();
120 System.arraycopy(names, 0, this.argNames, 1, names.length);
123 public String argString()
125 return argString(false);
128 public String negateArgString()
130 return argString(true);
133 private String argString(boolean negate)
135 StringBuilder sb = new StringBuilder(ArgParser.DOUBLEDASH);
136 if (negate && hasOption(Opt.BOOLEAN))
137 sb.append(ArgParser.NEGATESTRING);
138 sb.append(getName());
139 return sb.toString();
142 public String toLongString()
144 StringBuilder sb = new StringBuilder();
145 sb.append(this.getClass().getName()).append('.').append(this.name());
147 if (getNames().length > 0)
149 sb.append(String.join("\", \"", getNames()));
150 if (getNames().length > 0)
153 sb.append("\nOpt: ");
154 // map List<Opt> to List<String> for the String.join
155 List<String> optList = Arrays.asList(argOptions).stream()
156 .map(opt -> opt.name()).collect(Collectors.toList());
157 sb.append(String.join(", ", optList));
159 return sb.toString();
162 public String[] getNames()
167 public String getName()
169 return this.name().toLowerCase(Locale.ROOT).replace('_', '-');
173 public final String toString()
178 public boolean hasOption(Opt o)
180 if (argOptions == null)
182 for (Opt option : argOptions)
190 protected void setOptions(Opt... options)
192 setOptions("", false, options);
195 protected void setOptions(String desc, Opt... options)
197 setOptions(desc, false, options);
200 protected void setOptions(boolean defaultBoolValue, Opt... options)
202 setOptions("", defaultBoolValue, options);
205 protected void setOptions(String desc, boolean defaultBoolValue,
208 this.description = desc;
209 this.defaultBoolValue = defaultBoolValue;
210 this.argOptions = options;
213 protected boolean getDefaultBoolValue()
215 return defaultBoolValue;
218 private void setDescription(String d)
223 protected String getDescription()
228 public static String booleanArgString(Arg a)
230 StringBuilder sb = new StringBuilder(a.argString());
231 if (a.hasOption(Opt.BOOLEAN))
234 sb.append(a.negateArgString());
236 return sb.toString();
239 public static final String usage()
241 StringBuilder sb = new StringBuilder();
243 sb.append("Usage: jalview [args]");
244 sb.append(System.lineSeparator());
246 int maxArgLength = 0;
247 for (Arg a : EnumSet.allOf(Arg.class))
249 if (a.hasOption(Opt.PRIVATE))
251 StringBuilder argSb = new StringBuilder();
252 argSb.append(a.hasOption(Opt.BOOLEAN) ? booleanArgString(a)
254 if (a.hasOption(Opt.STRING))
255 argSb.append("=value");
256 if (argSb.length() > maxArgLength)
257 maxArgLength = argSb.length();
260 // might want to sort these
261 for (Arg a : EnumSet.allOf(Arg.class))
263 if (a.hasOption(Opt.PRIVATE))
265 StringBuilder argSb = new StringBuilder();
266 argSb.append(a.hasOption(Opt.BOOLEAN) ? booleanArgString(a)
268 if (a.hasOption(Opt.STRING))
269 argSb.append("=value");
270 sb.append(String.format("%-" + maxArgLength + "s - %s",
271 argSb.toString(), a.getDescription()));
273 List<String> options = new ArrayList<>();
275 if (a.hasOption(Opt.BOOLEAN))
277 options.add("default " + (a.getDefaultBoolValue() ? a.argString()
278 : a.negateArgString()));
281 if (a.hasOption(Opt.MULTI))
283 options.add("multiple");
286 if (a.hasOption(Opt.LINKED))
288 options.add("can be linked");
291 if (a.hasOption(Opt.GLOB))
293 options.add("allows file globs");
296 if (a.hasOption(Opt.ALLOWSUBSTITUTIONS))
298 options.add("allows substitutions");
301 if (options.size() > 0)
304 sb.append(String.join("; ", options));
307 sb.append(System.lineSeparator());
309 return sb.toString();