X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fbin%2FArgParser.java;h=be2c07f1f3f02705f55180ddc865aeccd52d2e63;hb=156ab6ab1046c02dc327c2ac986afa336f0bbf3b;hp=0f9ac2eaa8641ded060f8f6988936f6bbf0d62e6;hpb=c0e43acd458a2e19a5ab3be56a53bc88932657c4;p=jalview.git diff --git a/src/jalview/bin/ArgParser.java b/src/jalview/bin/ArgParser.java index 0f9ac2e..be2c07f 100644 --- a/src/jalview/bin/ArgParser.java +++ b/src/jalview/bin/ArgParser.java @@ -23,6 +23,7 @@ package jalview.bin; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Enumeration; @@ -58,7 +59,8 @@ public class ArgParser ANNOTATION2, DISPLAY, GUI, NEWS, NOQUESTIONNAIRE, SORTBYTREE, USAGESTATS, OPEN, OPEN2, PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC, VSESS, OUTPUT, OUTPUTTYPE, SSANNOTATION, NOTEMPFAC, TEMPFAC, - TEMPFAC_LABEL, TEMPFAC_DESC, TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP; + TEMPFAC_LABEL, TEMPFAC_DESC, TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP, + NOSTRUCTURE, STRUCTURE, IMAGE, QUIT, DEBUG("d"); static { @@ -102,10 +104,15 @@ public class ArgParser TEMPFAC.setOptions(Opt.STRING, Opt.LINKED); TEMPFAC_LABEL.setOptions(Opt.STRING, Opt.LINKED); TEMPFAC_DESC.setOptions(Opt.STRING, Opt.LINKED); - TEMPFAC_SHADING.setOptions(Opt.STRING, Opt.LINKED); + TEMPFAC_SHADING.setOptions(Opt.BOOLEAN, Opt.LINKED); TITLE.setOptions(Opt.STRING, Opt.LINKED); PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI); + NOSTRUCTURE.setOptions(Opt.UNARY, Opt.LINKED); + STRUCTURE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI); WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED); + IMAGE.setOptions(Opt.STRING, Opt.LINKED); + QUIT.setOptions(Opt.UNARY); + DEBUG.setOptions(Opt.BOOLEAN); } private final String[] argNames; @@ -208,12 +215,16 @@ public class ArgParser private boolean negated = false; - private List argsList; + private int singleArgIndex = -1; + + private List argsIndexes; + + private List argsList; protected ArgValues(Arg a) { this.arg = a; - this.argsList = new ArrayList(); + this.argsList = new ArrayList(); this.boolValue = arg.getDefaultBoolValue(); } @@ -267,8 +278,9 @@ public class ArgParser { sb.append("Values:"); boolean first = true; - for (String v : argsList) + for (ArgValue av : argsList) { + String v = av.getValue(); if (!first) sb.append(","); sb.append("\n '"); @@ -283,25 +295,24 @@ public class ArgParser protected void addValue() { - addValue(null); + addValue(null, -1); } - protected void addValue(String val) + protected void addValue(String val, int argIndex) { - addValue(val, false); + addValue(val, argIndex, false); } - protected void addValue(String val, boolean noDuplicates) + protected void addValue(String val, int argIndex, boolean noDuplicates) { if ((!arg.hasOption(Opt.MULTI) && argsList.size() > 0) || (noDuplicates && argsList.contains(val))) return; if (argsList == null) { - Console.warn("** inst"); - argsList = new ArrayList(); + argsList = new ArrayList(); } - argsList.add(val); + argsList.add(new ArgValue(val, argIndex)); } protected boolean hasValue(String val) @@ -309,14 +320,22 @@ public class ArgParser return argsList.contains(val); } - protected String getValue() + protected ArgValue getArgValue() { if (arg.hasOption(Opt.MULTI)) Console.warn("Requesting single value for multi value argument"); return argsList.size() > 0 ? argsList.get(0) : null; } - protected List getValues() + /* + protected String getValue() + { + ArgValue av = getArgValue(); + return av == null ? null : av.getValue(); + } + */ + + protected List getArgValueList() { return argsList; } @@ -449,7 +468,8 @@ public class ArgParser // new style Enumeration argE = Collections.enumeration(Arrays.asList(args)); - ARG: while (argE.hasMoreElements()) + int argIndex = 0; + while (argE.hasMoreElements()) { String arg = argE.nextElement(); String argName = null; @@ -492,14 +512,14 @@ public class ArgParser { // arg not found Console.error("Argument '" + arg + "' not recognised. Ignoring."); - continue ARG; + continue; } if (!a.hasOption(Opt.BOOLEAN) && negated) { // used "no" with a non-boolean option Console.error("Argument '--" + NEGATESTRING + argName + "' not a boolean option. Ignoring."); - continue ARG; + continue; } if (!a.hasOption(Opt.STRING) && equalPos > -1) { @@ -507,7 +527,7 @@ public class ArgParser Console.error("Argument '--" + argName + "' does not expect a value (given as '" + arg + "'). Ignoring."); - continue ARG; + continue; } if (!a.hasOption(Opt.LINKED) && linkedId != null) { @@ -515,7 +535,7 @@ public class ArgParser Console.error("Argument '--" + argName + "' does not expect a linked id (given as '" + arg + "'). Ignoring."); - continue ARG; + continue; } if (a.hasOption(Opt.STRING) && equalPos == -1) @@ -526,7 +546,7 @@ public class ArgParser // no value to take for arg, which wants a value Console.error("Argument '" + a.getName() + "' requires a value, none given. Ignoring."); - continue ARG; + continue; } val = argE.nextElement(); } @@ -550,7 +570,7 @@ public class ArgParser // store appropriate value if (a.hasOption(Opt.STRING)) { - values.addValue(val); + values.addValue(val, argIndex); } else if (a.hasOption(Opt.BOOLEAN)) { @@ -600,7 +620,7 @@ public class ArgParser public boolean getBool(Arg a) { - if (!a.hasOption(Opt.BOOLEAN)) + if (!a.hasOption(Opt.BOOLEAN) && !a.hasOption(Opt.UNARY)) { Console.warn("Getting boolean from non boolean Arg '" + a.getName() + "'."); @@ -663,4 +683,232 @@ public class ArgParser } return sb.toString(); } + + public static SubVals getSubVals(String item) + { + return new SubVals(item); + } + + /** + * A helper class to keep an index of argument position with argument values + */ + public static class ArgValue + { + private int argIndex; + + private String value; + + protected ArgValue(String value, int argIndex) + { + this.value = value; + this.argIndex = argIndex; + } + + protected String getValue() + { + return value; + } + + protected int getArgIndex() + { + return argIndex; + } + } + + /** + * A helper class to parse a string of the possible forms "content" + * "[index]content", "[keyName=keyValue]content" and return the integer index, + * the strings keyName and keyValue, and the content after the square brackets + * (if present). Values not set `will be -1 or null. + */ + public static class SubVals + { + private static int NOTSET = -1; + + private int index = NOTSET; + + private Map subVals = null; + + private static char SEPARATOR = ';'; + + private String content = null; + + public SubVals(String item) + { + this.parseVals(item); + } + + public void parseVals(String item) + { + if (item.indexOf('[') == 0 && item.indexOf(']') > 1) + { + int openBracket = item.indexOf('['); + int closeBracket = item.indexOf(']'); + String subvalsString = item.substring(openBracket + 1, + closeBracket); + this.content = item.substring(closeBracket + 1); + boolean setIndex = false; + for (String subvalString : subvalsString + .split(Character.toString(SEPARATOR))) + { + int equals = subvalString.indexOf('='); + if (equals > -1) + { + if (subVals == null) + subVals = new HashMap<>(); + subVals.put(subvalString.substring(0, equals), + subvalString.substring(equals + 1)); + } + else + { + try + { + this.index = Integer.parseInt(subvalString); + setIndex = true; + } catch (NumberFormatException e) + { + Console.warn("Failed to obtain subvalue or index from '" + + item + "'. Setting index=0 and using content='" + + content + "'."); + } + } + } + if (!setIndex) + this.index = NOTSET; + } + else + { + this.content = item; + } + } + + public boolean notSet() + { + // notSet is true if content present but nonsensical + return index == NOTSET && subVals == null; + } + + public String get(String key) + { + return subVals == null ? null : subVals.get(key); + } + + public boolean has(String key) + { + return subVals == null ? false : subVals.containsKey(key); + } + + public int getIndex() + { + return index; + } + + public String getContent() + { + return content; + } + } + + /** + * Helper class to allow easy extraction of information about specific + * argument values (without having to check for null etc all the time) + */ + protected static class ArgValuesMap + { + protected Map m; + + protected ArgValuesMap(Map map) + { + this.m = map; + } + + protected ArgValues getArgValues(Arg a) + { + return m == null ? null : m.get(a); + } + + protected List getArgValueList(Arg a) + { + ArgValues av = getArgValues(a); + return av == null ? null : av.getArgValueList(); + } + + protected ArgValue getArgValue(Arg a) + { + List vals = getArgValueList(a); + return (vals == null || vals.size() == 0) ? null : vals.get(0); + } + + protected String getValue(Arg a) + { + ArgValue av = getArgValue(a); + return av == null ? null : av.getValue(); + } + + protected boolean hasValue(Arg a) + { + if (!m.containsKey(a)) + return false; + return getArgValue(a) != null; + } + + protected boolean getBoolean(Arg a) + { + ArgValues av = getArgValues(a); + return av == null ? false : av.getBoolean(); + } + + protected ArgValue getClosestPreviousArgValueOfArg(ArgValue thisAv, + Arg a) + { + ArgValue closestAv = null; + int thisArgIndex = thisAv.getArgIndex(); + ArgValues compareAvs = this.getArgValues(a); + int closestPreviousIndex = -1; + for (ArgValue av : compareAvs.getArgValueList()) + { + int argIndex = av.getArgIndex(); + if (argIndex < thisArgIndex && argIndex > closestPreviousIndex) + { + closestPreviousIndex = argIndex; + closestAv = av; + } + } + return closestAv; + } + } + + private static final Collection bootstrapArgs = new ArrayList( + Arrays.asList(Arg.PROPS, Arg.DEBUG)); + + public static Map bootstrapArgs(String[] args) + { + Map bootstrapArgMap = new HashMap<>(); + if (args == null) + return bootstrapArgMap; + Enumeration argE = Collections.enumeration(Arrays.asList(args)); + while (argE.hasMoreElements()) + { + String arg = argE.nextElement(); + String argName = null; + String val = null; + if (arg.startsWith("--")) + { + int equalPos = arg.indexOf('='); + if (equalPos > -1) + { + argName = arg.substring(2, equalPos); + val = arg.substring(equalPos + 1); + } + else + { + argName = arg.substring(2); + } + Arg a = argMap.get(argName); + if (a != null && bootstrapArgs.contains(a)) + bootstrapArgMap.put(a, val); + } + } + return bootstrapArgMap; + } } \ No newline at end of file