JAL-629 More consistent printing of --arguments. Example nf-core argfile
[jalview.git] / src / jalview / bin / argparser / Arg.java
1 package jalview.bin.argparser;
2
3 import java.util.Arrays;
4 import java.util.List;
5 import java.util.Locale;
6 import java.util.stream.Collectors;
7
8 public enum Arg
9 {
10   HELP("h"), CALCULATION, MENUBAR, STATUS, SHOWOVERVIEW, ANNOTATIONS,
11   COLOUR, FEATURES, GROOVY, GROUPS, HEADLESS, JABAWS, ANNOTATION,
12   ANNOTATION2, DISPLAY, GUI, NEWS, SORTBYTREE, USAGESTATS, OPEN, OPENNEW,
13   PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC, VSESS, OUTPUT, OUTPUTTYPE,
14   SSANNOTATION, NOTEMPFAC, TEMPFAC, TEMPFAC_LABEL, TEMPFAC_DESC,
15   TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP, NOSTRUCTURE, STRUCTURE, IMAGE,
16   QUIT, CLOSE, DEBUG("d"), QUIET("q"), ARGFILE, INCREMENT, NPP("n++"),
17   SUBSTITUTIONS, INITSUBSTITUTIONS, NIL, SPLASH, SETARGFILE, UNSETARGFILE;
18
19   protected static enum Opt
20   {
21     BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES, BOOTSTRAP,
22     GLOB, NOACTION, ALLOWSUBSTITUTIONS, PRIVATE
23   }
24
25   static
26   {
27     HELP.setOptions(Opt.UNARY);
28     CALCULATION.setOptions(true, Opt.BOOLEAN); // default "true" implies only
29     // expecting "--nocalculation"
30     MENUBAR.setOptions(true, Opt.BOOLEAN);
31     STATUS.setOptions(true, Opt.BOOLEAN);
32     SHOWOVERVIEW.setOptions(Opt.UNARY, Opt.LINKED);
33     ANNOTATIONS.setOptions(Opt.STRING, Opt.LINKED);
34     COLOUR.setOptions(Opt.STRING, Opt.LINKED);
35     FEATURES.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
36             Opt.ALLOWSUBSTITUTIONS);
37     GROOVY.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
38             Opt.ALLOWSUBSTITUTIONS);
39     GROUPS.setOptions(Opt.STRING, Opt.LINKED);
40     HEADLESS.setOptions(Opt.UNARY, Opt.BOOTSTRAP);
41     JABAWS.setOptions(Opt.STRING);
42     ANNOTATION.setOptions(true, Opt.BOOLEAN, Opt.LINKED);
43     ANNOTATION2.setOptions(true, Opt.BOOLEAN, Opt.LINKED);
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     OPEN.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
52             Opt.ALLOWSUBSTITUTIONS);
53     OPENNEW.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);
59
60     VDOC.setOptions(Opt.UNARY);
61     VSESS.setOptions(Opt.UNARY);
62
63     OUTPUT.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
64     OUTPUTTYPE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
65
66     SSANNOTATION.setOptions(Opt.BOOLEAN, Opt.LINKED);
67     NOTEMPFAC.setOptions(Opt.UNARY, Opt.LINKED);
68     TEMPFAC.setOptions(Opt.STRING, Opt.LINKED);
69     TEMPFAC_LABEL.setOptions(Opt.STRING, Opt.LINKED);
70     TEMPFAC_DESC.setOptions(Opt.STRING, Opt.LINKED);
71     TEMPFAC_SHADING.setOptions(Opt.BOOLEAN, Opt.LINKED);
72     TITLE.setOptions(Opt.STRING, Opt.LINKED);
73     PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
74             Opt.ALLOWSUBSTITUTIONS);
75     NOSTRUCTURE.setOptions(Opt.UNARY, Opt.LINKED);
76     STRUCTURE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
77             Opt.ALLOWSUBSTITUTIONS);
78     WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED);
79     IMAGE.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
80     QUIT.setOptions(Opt.UNARY);
81     CLOSE.setOptions(Opt.UNARY, Opt.LINKED);
82     DEBUG.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
83     QUIET.setOptions(Opt.UNARY, Opt.MULTI, Opt.BOOTSTRAP);
84     ARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.GLOB,
85             Opt.ALLOWSUBSTITUTIONS);
86     INCREMENT.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
87     NPP.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
88     SUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION);
89     INITSUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION);
90     NIL.setOptions(Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.NOACTION);
91     SETARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
92     UNSETARGFILE.setOptions(Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
93     // Opt.BOOTSTRAP args are parsed (not linked with no SubVals so using a
94     // simplified parser, see jalview.bin.argparser.BootstrapArgs)
95     // before a full parse of arguments and so can be accessible at an earlier
96     // stage to (e.g.) set debug log level, provide a props file (that might set
97     // log level), run headlessly, read an argfile instead of other args.
98   }
99
100   private final String[] argNames;
101
102   private Opt[] argOptions;
103
104   private boolean defaultBoolValue = false;
105
106   private Arg()
107   {
108     this(new String[0]);
109   }
110
111   private Arg(String... names)
112   {
113     int length = (names == null || names.length == 0
114             || (names.length == 1 && names[0] == null)) ? 1
115                     : names.length + 1;
116     this.argNames = new String[length];
117     this.argNames[0] = this.getName();
118     if (length > 1)
119       System.arraycopy(names, 0, this.argNames, 1, names.length);
120   }
121
122   public String argString()
123   {
124     return new StringBuilder(ArgParser.DOUBLEDASH).append(getName())
125             .toString();
126   }
127
128   public String toLongString()
129   {
130     StringBuilder sb = new StringBuilder();
131     sb.append(this.getClass().getName()).append('.').append(this.name());
132     sb.append('(');
133     if (getNames().length > 0)
134       sb.append('"');
135     sb.append(String.join("\", \"", getNames()));
136     if (getNames().length > 0)
137       sb.append('"');
138     sb.append(")\n");
139     sb.append("\nOpt: ");
140     // map List<Opt> to List<String> for the String.join
141     List<String> optList = Arrays.asList(argOptions).stream()
142             .map(opt -> opt.name()).collect(Collectors.toList());
143     sb.append(String.join(", ", optList));
144     sb.append("\n");
145     return sb.toString();
146   }
147
148   public String[] getNames()
149   {
150     return argNames;
151   }
152
153   public String getName()
154   {
155     return this.name().toLowerCase(Locale.ROOT).replace('_', '-');
156   }
157
158   @Override
159   public final String toString()
160   {
161     return getName();
162   }
163
164   public boolean hasOption(Opt o)
165   {
166     if (argOptions == null)
167       return false;
168     for (Opt option : argOptions)
169     {
170       if (o == option)
171         return true;
172     }
173     return false;
174   }
175
176   protected void setOptions(Opt... options)
177   {
178     setOptions(false, options);
179   }
180
181   protected void setOptions(boolean defaultBoolValue, Opt... options)
182   {
183     this.defaultBoolValue = defaultBoolValue;
184     argOptions = options;
185   }
186
187   protected boolean getDefaultBoolValue()
188   {
189     return defaultBoolValue;
190   }
191 }