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, OPEN, OPENNEW, PROPS, QUESTIONNAIRE, SETPROP,
15 TREE, VDOC, VSESS, OUTPUT, OUTPUTTYPE, SSANNOTATIONS, NOTEMPFAC, TEMPFAC,
16 TITLE, PAEMATRIX, WRAP, NOSTRUCTURE, STRUCTURE, STRUCTUREVIEWER, IMAGE,
17 QUIT, CLOSE, DEBUG("d"), QUIET("q"), ARGFILE, INCREMENT, NPP("n++"),
18 SUBSTITUTIONS, INITSUBSTITUTIONS, NIL, SPLASH, SETARGFILE, UNSETARGFILE;
20 protected static enum Opt
22 BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES, BOOTSTRAP,
23 GLOB, NOACTION, ALLOWSUBSTITUTIONS, PRIVATE
28 HELP.setOptions("Display this help message", Opt.UNARY, Opt.BOOTSTRAP);
29 CALCULATION.setOptions(true, Opt.BOOLEAN); // default "true" implies only
30 // expecting "--nocalculation"
31 MENUBAR.setOptions(true, Opt.BOOLEAN);
32 STATUS.setOptions(true, Opt.BOOLEAN);
33 SHOWOVERVIEW.setOptions(Opt.UNARY, Opt.LINKED);
34 ANNOTATIONS.setOptions(Opt.BOOLEAN, Opt.LINKED);
35 COLOUR.setOptions(Opt.STRING, Opt.LINKED);
36 FEATURES.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
37 Opt.ALLOWSUBSTITUTIONS);
38 GROOVY.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
39 Opt.ALLOWSUBSTITUTIONS);
40 GROUPS.setOptions(Opt.STRING, Opt.LINKED);
41 HEADLESS.setOptions(Opt.UNARY, Opt.BOOTSTRAP);
42 JABAWS.setOptions(Opt.STRING);
43 DISPLAY.setOptions(true, Opt.BOOLEAN);
44 GUI.setOptions(true, Opt.BOOLEAN);
45 NEWS.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
46 SPLASH.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
47 // expects a string value
48 SORTBYTREE.setOptions(true, Opt.BOOLEAN);
49 USAGESTATS.setOptions(true, Opt.BOOLEAN);
50 OPEN.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
51 Opt.ALLOWSUBSTITUTIONS);
52 OPENNEW.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
53 Opt.ALLOWSUBSTITUTIONS);
54 PROPS.setOptions(Opt.STRING, Opt.BOOTSTRAP);
55 QUESTIONNAIRE.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
56 SETPROP.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP);
57 TREE.setOptions(Opt.STRING);
59 VDOC.setOptions(Opt.UNARY);
60 VSESS.setOptions(Opt.UNARY);
62 OUTPUT.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
63 OUTPUTTYPE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
65 SSANNOTATIONS.setOptions(Opt.BOOLEAN, Opt.LINKED);
66 NOTEMPFAC.setOptions(Opt.UNARY, Opt.LINKED);
67 TEMPFAC.setOptions(Opt.STRING, Opt.LINKED);
68 TITLE.setOptions(Opt.STRING, Opt.LINKED);
69 PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
70 Opt.ALLOWSUBSTITUTIONS);
71 NOSTRUCTURE.setOptions(Opt.UNARY, Opt.LINKED);
72 STRUCTURE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
73 Opt.ALLOWSUBSTITUTIONS);
74 STRUCTUREVIEWER.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
75 WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED);
76 IMAGE.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
77 QUIT.setOptions(Opt.UNARY);
78 CLOSE.setOptions(Opt.UNARY, Opt.LINKED);
79 DEBUG.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
80 QUIET.setOptions(Opt.UNARY, Opt.MULTI, Opt.BOOTSTRAP);
81 ARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.GLOB,
82 Opt.ALLOWSUBSTITUTIONS);
83 INCREMENT.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
84 NPP.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
85 SUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION);
86 INITSUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION);
87 NIL.setOptions(Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.NOACTION);
88 SETARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
89 UNSETARGFILE.setOptions(Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
90 // Opt.BOOTSTRAP args are parsed (not linked with no SubVals so using a
91 // simplified parser, see jalview.bin.argparser.BootstrapArgs)
92 // before a full parse of arguments and so can be accessible at an earlier
93 // stage to (e.g.) set debug log level, provide a props file (that might set
94 // log level), run headlessly, read an argfile instead of other args.
97 private final String[] argNames;
99 private Opt[] argOptions;
101 private boolean defaultBoolValue = false;
103 private String description = null;
110 private Arg(String... names)
112 int length = (names == null || names.length == 0
113 || (names.length == 1 && names[0] == null)) ? 1
115 this.argNames = new String[length];
116 this.argNames[0] = this.getName();
118 System.arraycopy(names, 0, this.argNames, 1, names.length);
121 public String argString()
123 return argString(false);
126 public String negateArgString()
128 return argString(true);
131 private String argString(boolean negate)
133 StringBuilder sb = new StringBuilder(ArgParser.DOUBLEDASH);
134 if (negate && hasOption(Opt.BOOLEAN))
135 sb.append(ArgParser.NEGATESTRING);
136 sb.append(getName());
137 return sb.toString();
140 public String toLongString()
142 StringBuilder sb = new StringBuilder();
143 sb.append(this.getClass().getName()).append('.').append(this.name());
145 if (getNames().length > 0)
147 sb.append(String.join("\", \"", getNames()));
148 if (getNames().length > 0)
151 sb.append("\nOpt: ");
152 // map List<Opt> to List<String> for the String.join
153 List<String> optList = Arrays.asList(argOptions).stream()
154 .map(opt -> opt.name()).collect(Collectors.toList());
155 sb.append(String.join(", ", optList));
157 return sb.toString();
160 public String[] getNames()
165 public String getName()
167 return this.name().toLowerCase(Locale.ROOT).replace('_', '-');
171 public final String toString()
176 public boolean hasOption(Opt o)
178 if (argOptions == null)
180 for (Opt option : argOptions)
188 protected void setOptions(Opt... options)
190 setOptions("", false, options);
193 protected void setOptions(String desc, Opt... options)
195 setOptions(desc, false, options);
198 protected void setOptions(boolean defaultBoolValue, Opt... options)
200 setOptions("", defaultBoolValue, options);
203 protected void setOptions(String desc, boolean defaultBoolValue,
206 this.description = desc;
207 this.defaultBoolValue = defaultBoolValue;
208 this.argOptions = options;
211 protected boolean getDefaultBoolValue()
213 return defaultBoolValue;
216 private void setDescription(String d)
221 protected String getDescription()
226 public static String booleanArgString(Arg a)
228 StringBuilder sb = new StringBuilder(a.argString());
229 if (a.hasOption(Opt.BOOLEAN))
232 sb.append(a.negateArgString());
234 return sb.toString();
237 public static final String usage()
239 StringBuilder sb = new StringBuilder();
241 sb.append("Usage: jalview [args]");
242 sb.append(System.lineSeparator());
244 int maxArgLength = 0;
245 for (Arg a : EnumSet.allOf(Arg.class))
247 if (a.hasOption(Opt.PRIVATE))
249 StringBuilder argSb = new StringBuilder();
250 argSb.append(a.hasOption(Opt.BOOLEAN) ? booleanArgString(a)
252 if (a.hasOption(Opt.STRING))
253 argSb.append("=value");
254 if (argSb.length() > maxArgLength)
255 maxArgLength = argSb.length();
258 // might want to sort these
259 for (Arg a : EnumSet.allOf(Arg.class))
261 if (a.hasOption(Opt.PRIVATE))
263 StringBuilder argSb = new StringBuilder();
264 argSb.append(a.hasOption(Opt.BOOLEAN) ? booleanArgString(a)
266 if (a.hasOption(Opt.STRING))
267 argSb.append("=value");
268 sb.append(String.format("%-" + maxArgLength + "s - %s",
269 argSb.toString(), a.getDescription()));
271 List<String> options = new ArrayList<>();
273 if (a.hasOption(Opt.BOOLEAN))
275 options.add("default " + (a.getDefaultBoolValue() ? a.argString()
276 : a.negateArgString()));
279 if (a.hasOption(Opt.MULTI))
281 options.add("multiple");
284 if (a.hasOption(Opt.LINKED))
286 options.add("can be linked");
289 if (a.hasOption(Opt.GLOB))
291 options.add("allows file globs");
294 if (a.hasOption(Opt.ALLOWSUBSTITUTIONS))
296 options.add("allows substitutions");
299 if (options.size() > 0)
302 sb.append(String.join("; ", options));
305 sb.append(System.lineSeparator());
307 return sb.toString();