From ccc53e88e3260886f5d3bdacc619c0f374be9b8f Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Wed, 6 Dec 2023 17:41:35 +0000 Subject: [PATCH] JAL-4353 Preserve the user given 'linkedId' with ArgValue, to help with deciding if user deliberately set a wildcard linkedId (or --all), to inform value of sub-args. --- src/jalview/bin/argparser/Arg.java | 22 +++---- src/jalview/bin/argparser/ArgParser.java | 90 +++++++++++++++------------ src/jalview/bin/argparser/ArgValue.java | 52 +++++++++++++++- src/jalview/bin/argparser/ArgValues.java | 27 ++++++-- src/jalview/bin/argparser/ArgValuesMap.java | 56 +++++++++++++---- src/jalview/util/ColorUtils.java | 3 +- 6 files changed, 179 insertions(+), 71 deletions(-) diff --git a/src/jalview/bin/argparser/Arg.java b/src/jalview/bin/argparser/Arg.java index cdb29bf..9a05c9f 100644 --- a/src/jalview/bin/argparser/Arg.java +++ b/src/jalview/bin/argparser/Arg.java @@ -681,24 +681,22 @@ public enum Arg return this.types; } - public boolean hasType(Type t) + public boolean sharesType(Arg a) { - for (Type type : getTypes()) - { - if (type == t) - { - return true; - } - } - return false; + return this.hasType(a.getTypes()); } - public boolean sharesType(Arg a) + public boolean hasType(Type... types) + { + Set typesSet = new HashSet<>(Arrays.asList(types)); + return this.hasType(typesSet); + } + + public boolean hasType(Set typesSet) { - List aTypes = Arrays.asList(a.getTypes()); for (Type type : getTypes()) { - if (aTypes.contains(type)) + if (typesSet.contains(type)) { return true; } diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index fe73053..12e1b1d 100644 --- a/src/jalview/bin/argparser/ArgParser.java +++ b/src/jalview/bin/argparser/ArgParser.java @@ -365,6 +365,8 @@ public class ArgParser List globVals = null; // for Opt.GLOB only SubVals globSubVals = null; // also for use by Opt.GLOB only String linkedId = null; + String givenLinkedId = null; // this is preserved to add to each + // "ArgValue" Type type = null; // look for equals e.g. --arg=value @@ -385,6 +387,7 @@ public class ArgParser if (idOpen > -1 && idClose == argName.length() - 1) { linkedId = argName.substring(idOpen + 1, idClose); + givenLinkedId = linkedId; argName = argName.substring(0, idOpen); } @@ -595,6 +598,12 @@ public class ArgParser { linkedId = MATCHALLLINKEDIDS; } + if (allLinkedIds) + { + // user has made conscious decision for these args to apply to + // all, so set givenLinkedId too + givenLinkedId = linkedId; + } else if (a.hasOption(Opt.ALLOWMULTIID) && this.storedLinkedIds != null && this.storedLinkedIds.size() > 0) @@ -686,7 +695,8 @@ public class ArgParser { String v = gve.nextElement(); SubVals vsv = new SubVals(globSubVals, v); - addValue(linkedId, type, avs, vsv, v, argIndex++, true); + addValue(linkedId, givenLinkedId, type, avs, vsv, v, + argIndex++, true); // if we're using defaultLinkedId and the arg increments the // counter: if (gve.hasMoreElements() && usingDefaultLinkedId @@ -703,18 +713,19 @@ public class ArgParser else { // addValue(linkedId, type, avs, val, argIndex, true); - addValue(linkedId, type, avs, addNewSubVals ? subvals : null, - val, argIndex, true); + addValue(linkedId, givenLinkedId, type, avs, + addNewSubVals ? subvals : null, val, argIndex, true); } } else if (a.hasOption(Opt.BOOLEAN)) { - setBoolean(linkedId, type, avs, !negated, argIndex); + setBoolean(linkedId, givenLinkedId, type, avs, !negated, + argIndex); setNegated(linkedId, avs, negated); } else if (a.hasOption(Opt.UNARY)) { - setBoolean(linkedId, type, avs, true, argIndex); + setBoolean(linkedId, givenLinkedId, type, avs, true, argIndex); } // remove the '*' or 'open*' linkedId that should be empty if it was @@ -1055,30 +1066,30 @@ public class ArgParser /** * This version inserts the subvals sv into all created values */ - private void addValue(String linkedId, Type type, ArgValues avs, - SubVals sv, String v, int argIndex, boolean doSubs) + private void addValue(String linkedId, String givenLinkedId, Type type, + ArgValues avs, SubVals sv, String v, int argIndex, boolean doSubs) { - this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, sv, v, false, - argIndex, doSubs); + this.argValueOperation(Op.ADDVALUE, linkedId, givenLinkedId, type, avs, + sv, v, false, argIndex, doSubs); } - private void setBoolean(String linkedId, Type type, ArgValues avs, - boolean b, int argIndex) + private void setBoolean(String linkedId, String givenLinkedId, Type type, + ArgValues avs, boolean b, int argIndex) { - this.argValueOperation(Op.SETBOOLEAN, linkedId, type, avs, null, null, - b, argIndex, false); + this.argValueOperation(Op.SETBOOLEAN, linkedId, givenLinkedId, type, + avs, null, null, b, argIndex, false); } private void setNegated(String linkedId, ArgValues avs, boolean b) { - this.argValueOperation(Op.SETNEGATED, linkedId, null, avs, null, null, - b, 0, false); + this.argValueOperation(Op.SETNEGATED, linkedId, null, null, avs, null, + null, b, 0, false); } private void incrementCount(String linkedId, ArgValues avs) { - this.argValueOperation(Op.INCREMENTCOUNT, linkedId, null, avs, null, - null, false, 0, false); + this.argValueOperation(Op.INCREMENTCOUNT, linkedId, null, null, avs, + null, null, false, 0, false); } private enum Op @@ -1086,13 +1097,13 @@ public class ArgParser ADDVALUE, SETBOOLEAN, SETNEGATED, INCREMENTCOUNT } - private void argValueOperation(Op op, String linkedId, Type type, - ArgValues avs, SubVals sv, String v, boolean b, int argIndex, - boolean doSubs) + private void argValueOperation(Op op, String linkedId, + String givenLinkedId, Type type, ArgValues avs, SubVals sv, + String v, boolean b, int argIndex, boolean doSubs) { // default to merge subvals if subvals are provided - argValueOperation(op, linkedId, type, avs, sv, true, v, b, argIndex, - doSubs); + argValueOperation(op, linkedId, givenLinkedId, type, avs, sv, true, v, + b, argIndex, doSubs); } /** @@ -1122,9 +1133,9 @@ public class ArgParser * @param doSubs * Whether to perform substitutions on the subvals and value. */ - private void argValueOperation(Op op, String linkedId, Type type, - ArgValues avs, SubVals sv, boolean merge, String v, boolean b, - int argIndex, boolean doSubs) + private void argValueOperation(Op op, String linkedId, + String givenLinkedId, Type type, ArgValues avs, SubVals sv, + boolean merge, String v, boolean b, int argIndex, boolean doSubs) { Arg a = avs.arg(); @@ -1155,15 +1166,16 @@ public class ArgParser // linkedIds if (wildcardLinkedIds != null) { - for (String id : wildcardLinkedIds) + for (String matchedLinkedId : wildcardLinkedIds) { // skip incorrectly stored wildcard ids! - if (id == null || MATCHALLLINKEDIDS.equals(id) - || MATCHOPENEDLINKEDIDS.equals(id)) + if (matchedLinkedId == null + || MATCHALLLINKEDIDS.equals(matchedLinkedId) + || MATCHOPENEDLINKEDIDS.equals(matchedLinkedId)) { continue; } - ArgValuesMap avm = linkedArgs.get(id); + ArgValuesMap avm = linkedArgs.get(matchedLinkedId); // don't set an output if there isn't an input if (a.hasOption(Opt.REQUIREINPUT) && !avm.hasArgWithOption(Opt.INPUT)) @@ -1180,24 +1192,24 @@ public class ArgParser if (doSubs) { sv = new SubVals(sv, val, merge); - val = makeSubstitutions(sv.getContent(), id); + val = makeSubstitutions(sv.getContent(), matchedLinkedId); } - tavs.addValue(sv, type, val, argIndex, true); + tavs.addValue(sv, type, val, argIndex, true, givenLinkedId); } else { if (doSubs) { - val = makeSubstitutions(v, id); + val = makeSubstitutions(v, matchedLinkedId); } - tavs.addValue(type, val, argIndex, true); + tavs.addValue(type, val, argIndex, true, givenLinkedId); } - finaliseStoringArgValue(id, tavs); + finaliseStoringArgValue(matchedLinkedId, tavs); break; case SETBOOLEAN: - tavs.setBoolean(type, b, argIndex, true); - finaliseStoringArgValue(id, tavs); + tavs.setBoolean(type, b, argIndex, true, givenLinkedId); + finaliseStoringArgValue(matchedLinkedId, tavs); break; case SETNEGATED: @@ -1228,7 +1240,7 @@ public class ArgParser val = makeSubstitutions(v, linkedId); sv = new SubVals(sv, val); } - avs.addValue(sv, type, val, argIndex, false); + avs.addValue(sv, type, val, argIndex, false, givenLinkedId); } else { @@ -1236,13 +1248,13 @@ public class ArgParser { val = makeSubstitutions(v, linkedId); } - avs.addValue(type, val, argIndex, false); + avs.addValue(type, val, argIndex, false, givenLinkedId); } finaliseStoringArgValue(linkedId, avs); break; case SETBOOLEAN: - avs.setBoolean(type, b, argIndex, false); + avs.setBoolean(type, b, argIndex, false, givenLinkedId); finaliseStoringArgValue(linkedId, avs); break; diff --git a/src/jalview/bin/argparser/ArgValue.java b/src/jalview/bin/argparser/ArgValue.java index eab38ca..e7ee1a2 100644 --- a/src/jalview/bin/argparser/ArgValue.java +++ b/src/jalview/bin/argparser/ArgValue.java @@ -34,6 +34,12 @@ public class ArgValue implements Comparable private String value; + private String givenLinkedId = null; + + private String assignedLinkedId = null; + + private boolean setByWildcardLinkedId = false; + /* * Type type is only really used by --help-type */ @@ -48,22 +54,31 @@ public class ArgValue implements Comparable private SubVals subVals; protected ArgValue(Arg a, SubVals sv, Type type, String content, - int argIndex) + int argIndex, boolean setByWildcardLinkedId, String givenLinkedId, + String assignedLinkedId) { this.arg = a; this.value = content; this.argIndex = argIndex; this.subVals = sv == null ? new SubVals("") : sv; this.setType(type); + this.setByWildcardLinkedId = setByWildcardLinkedId; + this.givenLinkedId = givenLinkedId; + this.assignedLinkedId = assignedLinkedId; } - protected ArgValue(Arg a, Type type, String value, int argIndex) + protected ArgValue(Arg a, Type type, String value, int argIndex, + boolean setByWildcardLinkedId, String givenLinkedId, + String assignedLinkedId) { this.arg = a; this.argIndex = argIndex; this.subVals = new SubVals(value); this.value = getSubVals().getContent(); this.setType(type); + this.setByWildcardLinkedId = setByWildcardLinkedId; + this.givenLinkedId = givenLinkedId; + this.assignedLinkedId = assignedLinkedId; } protected void setType(Type t) @@ -124,4 +139,37 @@ public class ArgValue implements Comparable { return this.getArgIndex() - o.getArgIndex(); } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append(this.getArg().argString()); + sb.append("="); + if (!this.getSubVals().getSubValMap().isEmpty()) + { + sb.append(this.getSubVals().toString()); + } + sb.append("'"); + sb.append(this.getValue()); + sb.append("'"); + + return sb.toString(); + } + + public String getGivenLinkedId() + { + return this.givenLinkedId; + } + + public String getAssignedLinkedId() + { + return this.assignedLinkedId; + } + + public boolean setByWildcardLinkedId() + { + // looking for deliberately user set wildcard + return this.setByWildcardLinkedId && this.getGivenLinkedId() != null; + } } \ No newline at end of file diff --git a/src/jalview/bin/argparser/ArgValues.java b/src/jalview/bin/argparser/ArgValues.java index 8e4fe2c..55e1211 100644 --- a/src/jalview/bin/argparser/ArgValues.java +++ b/src/jalview/bin/argparser/ArgValues.java @@ -44,6 +44,8 @@ public class ArgValues private boolean setByWildcard = false; + private String givenLinkedId = null; + private int boolIndex = -1; private List argsIndexes; @@ -52,16 +54,19 @@ public class ArgValues private Map idMap = new HashMap<>(); + private ArgValuesMap avm; + /* * Type type is only really used by --help-type */ private Type type = null; - protected ArgValues(Arg a) + protected ArgValues(Arg a, ArgValuesMap avm) { this.arg = a; this.argValueList = new ArrayList(); this.boolValue = arg.getDefaultBoolValue(); + this.avm = avm; } protected boolean setByWildcard() @@ -114,7 +119,7 @@ public class ArgValues } protected void setBoolean(Type t, boolean b, int i, - boolean beingSetByWildcard) + boolean beingSetByWildcard, String givenLinkedId) { this.setType(t); // don't overwrite a wildcard set boolean with a non-wildcard set boolean @@ -123,6 +128,7 @@ public class ArgValues this.boolValue = b; this.boolIndex = i; this.setSetByWildcard(beingSetByWildcard); + this.givenLinkedId = givenLinkedId; } protected boolean getBoolean() @@ -157,15 +163,17 @@ public class ArgValues } protected void addValue(Type type, String val, int argIndex, - boolean wildcard) + boolean wildcard, String givenLinkedId) { - addArgValue(new ArgValue(arg(), type, val, argIndex), wildcard); + addArgValue(new ArgValue(arg(), type, val, argIndex, wildcard, + givenLinkedId, avm.getLinkedId()), wildcard); } protected void addValue(SubVals sv, Type type, String content, - int argIndex, boolean wildcard) + int argIndex, boolean wildcard, String givenLinkedId) { - addArgValue(new ArgValue(arg(), sv, type, content, argIndex), wildcard); + addArgValue(new ArgValue(arg(), sv, type, content, argIndex, wildcard, + givenLinkedId, avm.getLinkedId()), wildcard); } protected void addArgValue(ArgValue av, boolean beingSetByWildcard) @@ -238,4 +246,11 @@ public class ArgValues } return false; } + + public boolean setByWildcardLinkedId() + { + // looking for deliberately user set wildcard + return this.setByWildcard && this.givenLinkedId != null; + } + } \ No newline at end of file diff --git a/src/jalview/bin/argparser/ArgValuesMap.java b/src/jalview/bin/argparser/ArgValuesMap.java index 5d53641..8a28b87 100644 --- a/src/jalview/bin/argparser/ArgValuesMap.java +++ b/src/jalview/bin/argparser/ArgValuesMap.java @@ -22,8 +22,10 @@ package jalview.bin.argparser; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -77,9 +79,13 @@ public class ArgValuesMap private void newArg(Arg a) { if (m == null) + { newMap(); + } if (!containsArg(a)) - m.put(a, new ArgValues(a)); + { + m.put(a, new ArgValues(a, this)); + } } public ArgValues getArgValues(Arg a) @@ -105,16 +111,27 @@ public class ArgValuesMap SubVals sv) { return getArgValueListFromSubValArgOrPrefWithSubstitutionsWithinTypes( - null, a, Position.AFTER, av, sv, null, null, null, true); + null, a, Position.AFTER, av, sv, null, null, null, true, null); } public List getArgValueListFromSubValArgOrPrefWithSubstitutionsWithinTypes( ArgParser ap, Arg a, ArgValuesMap.Position pos, ArgValue av, SubVals sv, String key, String pref, String def, - boolean withinTypes) + boolean withinTypes, Type type) { if (key == null) + { key = a.getName(); + } + Set types = new HashSet<>(); + if (type == null) + { + types.addAll(Arrays.asList(av.getArg().getTypes())); + } + else + { + types.add(type); + } List avList = new ArrayList<>(); if (sv != null && sv.has(key) && sv.get(key) != null) { @@ -123,7 +140,9 @@ public class ArgValuesMap // protected ArgValue(Arg a, SubVals sv, Type type, String content, int // argIndex) - avList.add(new ArgValue(a, null, null, value, av.getArgIndex())); + ArgValue svav = new ArgValue(a, null, null, value, av.getArgIndex(), + false, null, this.getLinkedId()); + avList.add(svav); } else if (containsArg(a)) { @@ -163,8 +182,9 @@ public class ArgValuesMap // run through every Arg used in this ArgValuesMap for (Arg tmpA : this.getArgKeys()) { - // only interested in Opt.PRIMARY args of the same type - if (tmpA.sharesType(a) && tmpA.hasOption(Opt.PRIMARY)) + // only interested in looking up to next Opt.PRIMARY args of the same + // type as av (or provided type) + if (tmpA.hasType(types) && tmpA.hasOption(Opt.PRIMARY)) { for (ArgValue tmpAv : getArgValueList(tmpA)) { @@ -177,15 +197,17 @@ public class ArgValuesMap } } } - List tmpList = List.copyOf(avList); - for (ArgValue tmpAv : tmpList) + List tmpList = new ArrayList<>(); + for (ArgValue tmpAv : avList) { - if (nextPrimaryArgOfSameTypeIndex < tmpAv.getArgIndex()) + int tmpAvIndex = tmpAv.getArgIndex(); + if (av.getArgIndex() < tmpAvIndex + && tmpAvIndex < nextPrimaryArgOfSameTypeIndex) { - // looks like this tmpAv actually belongs to a different primary Arg - avList.remove(tmpAv); + tmpList.add(tmpAv); } } + avList = tmpList; } return avList; @@ -521,6 +543,18 @@ public class ArgValuesMap value = av2.getValue(); } } + + if (value == null) + { + // look for --all --a occurrences + for (ArgValue tmpAv : this.getArgValueList(a)) + { + if (tmpAv.setByWildcardLinkedId()) + { + value = tmpAv.getValue(); + } + } + } } if (value == null) { diff --git a/src/jalview/util/ColorUtils.java b/src/jalview/util/ColorUtils.java index e9c66bd..0e44f34 100644 --- a/src/jalview/util/ColorUtils.java +++ b/src/jalview/util/ColorUtils.java @@ -267,7 +267,8 @@ public class ColorUtils int b = Integer.parseInt(tokens[2].trim()); col = new Color(r, g, b); } - } catch (Exception ex) + } catch (IllegalArgumentException ex) // IllegalArgumentException includes + // NumberFormatException { // non-numeric token or out of 0-255 range } -- 1.7.10.2