From: James Procter Date: Tue, 12 Dec 2023 16:02:14 +0000 (+0000) Subject: Merge branch 'develop' into bug/JAL-4353_cannot_output_multiple_different_structure_i... X-Git-Tag: Release_2_11_3_3~8^2~1^2~2^2 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=751db101d2ecf173e997729438b96b668900dee8;hp=deb7e7788d802d45cc6b2f8a5a04285308f1e8ee;p=jalview.git Merge branch 'develop' into bug/JAL-4353_cannot_output_multiple_different_structure_images_for_one_alignment --- diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index 475eba2..e01d40a 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -501,15 +501,13 @@ public class Commands if (avm.containsArg(Arg.STRUCTURE)) { commandArgsProvided = true; - for ( - - ArgValue av : avm.getArgValueList(Arg.STRUCTURE)) + for (ArgValue structureAv : avm.getArgValueList(Arg.STRUCTURE)) { argParser.setStructureFilename(null); - String val = av.getValue(); - SubVals subVals = av.getSubVals(); - int argIndex = av.getArgIndex(); - SequenceI seq = getSpecifiedSequence(af, avm, av); + String val = structureAv.getValue(); + SubVals subVals = structureAv.getSubVals(); + int argIndex = structureAv.getArgIndex(); + SequenceI seq = getSpecifiedSequence(af, avm, structureAv); if (seq == null) { // Could not find sequence from subId, let's assume the first @@ -578,8 +576,8 @@ public class Commands // get PAEMATRIX file and label from subvals or Arg.PAEMATRIX String paeFilepath = avm.getFromSubValArgOrPrefWithSubstitutions( - argParser, Arg.PAEMATRIX, ArgValuesMap.Position.AFTER, av, - subVals, null, null, null); + argParser, Arg.PAEMATRIX, ArgValuesMap.Position.AFTER, + structureAv, subVals, null, null, null); if (paeFilepath != null) { File paeFile = new File(paeFilepath); @@ -603,8 +601,8 @@ public class Commands // get TEMPFAC type from subvals or Arg.TEMPFAC in case user Adds // reference annotations String tftString = avm.getFromSubValArgOrPrefWithSubstitutions( - argParser, Arg.TEMPFAC, ArgValuesMap.Position.AFTER, av, - subVals, null, null, null); + argParser, Arg.TEMPFAC, ArgValuesMap.Position.AFTER, + structureAv, subVals, null, null, null); boolean notempfac = avm.getFromSubValArgOrPref(Arg.NOTEMPFAC, subVals, null, "ADD_TEMPFACT_ANN", false, true); TFType tft = notempfac ? null : TFType.DEFAULT; @@ -636,8 +634,8 @@ public class Commands } String sViewerName = avm.getFromSubValArgOrPref( - Arg.STRUCTUREVIEWER, ArgValuesMap.Position.AFTER, av, - subVals, null, null, "jmol"); + Arg.STRUCTUREVIEWER, ArgValuesMap.Position.AFTER, + structureAv, subVals, null, null, "jmol"); ViewerType viewerType = ViewerType.getFromString(sViewerName); // TODO use ssFromStructure @@ -698,7 +696,8 @@ public class Commands if (avm.containsArg(Arg.STRUCTUREIMAGE)) { for (ArgValue structureImageArgValue : avm - .getArgValueList(Arg.STRUCTUREIMAGE)) + .getArgValueListFromSubValOrArg(structureAv, + Arg.STRUCTUREIMAGE, subVals)) { String structureImageFilename = argParser.makeSubstitutions( structureImageArgValue.getValue(), id, true); diff --git a/src/jalview/bin/argparser/Arg.java b/src/jalview/bin/argparser/Arg.java index d043d16..9a05c9f 100644 --- a/src/jalview/bin/argparser/Arg.java +++ b/src/jalview/bin/argparser/Arg.java @@ -25,9 +25,11 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.stream.Collectors; import jalview.bin.argparser.Arg.Opt; @@ -181,7 +183,8 @@ public enum Arg + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.", Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.MULTIVALUE, Opt.ALLOWMULTIID, Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.PRIMARY), - STRUCTUREIMAGE(Type.IMAGE, + STRUCTUREIMAGE(new Type[] + { Type.IMAGE, Type.STRUCTUREIMAGE }, "Export an image of a 3D structure opened in JMOL", Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.OUTPUTFILE, Opt.ALLOWMULTIID, Opt.PRIMARY), @@ -213,26 +216,6 @@ public enum Arg BGCOLOUR(Type.IMAGE, "bgcolor", // being a bit soft on the Americans! "Applies a background colour to the structure image. Valid values are named colours known to Java or RRGGBB 6 digit hex-string.", Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), - /* - STRUCTUREIMAGETYPE(Type.IMAGE, - "Set the structure image format for the preceding --structureimage. Valid values are:\n" - + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.", - Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), - STRUCTUREIMAGETEXTRENDERER(Type.IMAGE, - "Sets whether text in a vector structure image format (SVG, EPS) should be rendered as text or vector line-art. Possible values are:\n" - + "text,\n" + "lineart.", - Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), - STRUCTUREIMAGESCALE(Type.IMAGE, - "Sets a scaling for bitmap structure image format (PNG). Should be given as a floating point number. If used in conjunction with --structureimagewidth and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), - STRUCTUREIMAGEWIDTH(Type.IMAGE, - "Sets a width for bitmap structure image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), - STRUCTUREIMAGEHEIGHT(Type.IMAGE, - "Sets a height for bitmap structure image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimagewidth then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), - */ - OUTPUT(Type.OUTPUT, "Export the open alignment to file filename. The format name is specified by the subval modifier format=name, a following --format name argument or guessed from the file extension. Valid format names (and file extensions) are:\n" + "fasta (fa, fasta, mfa, fastq),\n" + "pfam (pfam),\n" @@ -499,9 +482,8 @@ public enum Arg STRUCTURE("arguments used to add and format 3D structure data"), PROCESS("arguments used to process an alignment once opened"), OUTPUT("arguments used to save data from a processed alignment"), - IMAGE("arguments used to export an image of an alignment or structure"), - // IMAGE("arguments used to export an image of an alignment"), - // STRUCTUREIMAGE("arguments used to export an image of an structure"), + IMAGE("arguments used to export an image of an alignment"), + STRUCTUREIMAGE("arguments used to export an image of an structure"), FLOW("arguments that control processing of the other arguments"), // ALL("all arguments"), // mostly just a place-holder for --help-all NONE, // mostly a place-holder for --help @@ -533,29 +515,53 @@ public enum Arg private String description; - private Type type; + private Type[] types; private Arg(Type type, String description, Opt... options) { + this(new Type[] { type }, description, options); + } + + private Arg(Type[] type, String description, Opt... options) + { this(type, null, description, false, options); } private Arg(Type type, String description, boolean defaultBoolean, Opt... options) { + this(new Type[] { type }, description, defaultBoolean, options); + } + + private Arg(Type[] type, String description, boolean defaultBoolean, + Opt... options) + { this(type, null, description, defaultBoolean, options); } private Arg(Type type, String alternativeName, String description, Opt... options) { + this(new Type[] { type }, alternativeName, description, options); + } + + private Arg(Type[] type, String alternativeName, String description, + Opt... options) + { this(type, alternativeName, description, false, options); } private Arg(Type type, String alternativeName, String description, boolean defaultBoolean, Opt... options) { - this.type = type; + this(new Type[] { type }, alternativeName, description, defaultBoolean, + options); + } + + private Arg(Type[] type, String alternativeName, String description, + boolean defaultBoolean, Opt... options) + { + this.types = type; this.description = description; this.defaultBoolValue = defaultBoolean; this.setOptions(options); @@ -596,7 +602,11 @@ public enum Arg if (getNames().length > 0) sb.append('"'); sb.append(")\n"); - sb.append("\nType: " + type.name()); + for (Type type : getTypes()) + { + String typeName = type.name(); + sb.append("\nType: " + typeName); + } sb.append("\nOpt: "); // map List to List for the String.join List optList = Arrays.asList(argOptions).stream() @@ -661,9 +671,37 @@ public enum Arg return defaultBoolValue; } - public Type getType() + public Type getFirstType() { - return this.type; + return this.getTypes()[0]; + } + + public Type[] getTypes() + { + return this.types; + } + + public boolean sharesType(Arg a) + { + return this.hasType(a.getTypes()); + } + + public boolean hasType(Type... types) + { + Set typesSet = new HashSet<>(Arrays.asList(types)); + return this.hasType(typesSet); + } + + public boolean hasType(Set typesSet) + { + for (Type type : getTypes()) + { + if (typesSet.contains(type)) + { + return true; + } + } + return false; } protected String getDescription() @@ -690,9 +728,17 @@ public enum Arg public static final void appendUsageGeneral(StringBuilder sb, int maxArgLength) { + Set firstTypes = new HashSet<>(); + for (Arg a : EnumSet.allOf(Arg.class)) + { + if (!firstTypes.contains(a.getFirstType())) + { + firstTypes.add(a.getFirstType()); + } + } for (Type t : EnumSet.allOf(Type.class)) { - if (t.description() != null) + if (t.description() != null && firstTypes.contains(t)) { StringBuilder argSb = new StringBuilder(); argSb.append(Arg.HELP.argString()).append(ArgParser.SINGLEDASH) @@ -727,20 +773,6 @@ public enum Arg { List args = argsSortedForDisplay(types); - /* - * just use a set maxArgLength of DESCRIPTIONINDENT - - int maxArgLength = 0; - for (Arg a : args) - { - if (a.hasOption(Opt.PRIVATE) || a.hasOption(Opt.SECRET)) - continue; - - String argS = argDisplayString(a); - if (argS.length() > maxArgLength) - maxArgLength = argS.length(); - } - */ int maxArgLength = DESCRIPTIONINDENT; // always show --help @@ -764,10 +796,10 @@ public enum Arg continue; } - if (a.getType() != typeSection) + if (a.getFirstType() != typeSection) { - typeSection = a.getType(); - String typeDescription = a.getType().description(); + typeSection = a.getFirstType(); + String typeDescription = a.getFirstType().description(); if (typeDescription != null && typeDescription.length() > 0) { // typeDescription = typeDescription.substring(0, @@ -958,7 +990,7 @@ public enum Arg { Opt[] opts = options == null ? new Opt[] {} : options; return EnumSet.allOf(Arg.class).stream().filter(a -> { - if (a.getType() != type) + if (!a.hasType(type)) return false; for (Opt o : opts) { @@ -1013,7 +1045,7 @@ class ArgDisplayComparator implements Comparator if (b == null) return -1; // first compare types (in enum order) - int i = a.getType().compareTo(b.getType()); + int i = a.getFirstType().compareTo(b.getFirstType()); if (i != 0) return i; // do Opt.LAST next (oddly). Reversed args important! diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index 155f69e..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) @@ -661,7 +670,7 @@ public class ArgParser // set allstructures to all non-primary structure options in this linked // id if --allstructures has been set - if (allStructures && (a.getType() == Type.STRUCTURE + if (allStructures && (a.hasType(Type.STRUCTURE) // || a.getType() == Type.STRUCTUREIMAGE) ) && !a.hasOption(Opt.PRIMARY)) { @@ -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 fc1e090..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) @@ -101,6 +107,112 @@ public class ArgValuesMap return avs == null ? new ArrayList<>() : avs.getArgValueList(); } + public List getArgValueListFromSubValOrArg(ArgValue av, Arg a, + SubVals sv) + { + return getArgValueListFromSubValArgOrPrefWithSubstitutionsWithinTypes( + 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, 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) + { + String value = ap == null ? sv.get(key) + : sv.getWithSubstitutions(ap, getLinkedId(), key); + // protected ArgValue(Arg a, SubVals sv, Type type, String content, int + // argIndex) + + ArgValue svav = new ArgValue(a, null, null, value, av.getArgIndex(), + false, null, this.getLinkedId()); + avList.add(svav); + } + else if (containsArg(a)) + { + if (pos == ArgValuesMap.Position.FIRST && getValue(a) != null) + avList.add(getArgValue(a)); + else if (pos == ArgValuesMap.Position.BEFORE + && getClosestPreviousArgValueOfArg(av, a) != null) + { + for (ArgValue tmpAv : getArgValues(a).getArgValueList()) + { + if (tmpAv.getArgIndex() >= av.getArgIndex()) + { + continue; + } + avList.add(tmpAv); + } + } + else if (pos == ArgValuesMap.Position.AFTER + && getClosestNextArgValueOfArg(av, a, withinTypes) != null) + { + for (ArgValue tmpAv : getArgValues(a).getArgValueList()) + { + if (tmpAv.getArgIndex() <= av.getArgIndex()) + { + continue; + } + avList.add(tmpAv); + } + } + } + + // check if withinType the avs don't belong to the next primary arg + // of this type. Checking for *any* shared type. + if (withinTypes && !avList.isEmpty()) + { + int nextPrimaryArgOfSameTypeIndex = Integer.MAX_VALUE; + // run through every Arg used in this ArgValuesMap + for (Arg tmpA : this.getArgKeys()) + { + // 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)) + { + int tmpArgIndex = tmpAv.getArgIndex(); + if (tmpArgIndex > av.getArgIndex() + && tmpArgIndex < nextPrimaryArgOfSameTypeIndex) + { + nextPrimaryArgOfSameTypeIndex = tmpArgIndex; + } + } + } + } + List tmpList = new ArrayList<>(); + for (ArgValue tmpAv : avList) + { + int tmpAvIndex = tmpAv.getArgIndex(); + if (av.getArgIndex() < tmpAvIndex + && tmpAvIndex < nextPrimaryArgOfSameTypeIndex) + { + tmpList.add(tmpAv); + } + } + avList = tmpList; + } + + return avList; + } + public ArgValue getArgValue(Arg a) { List vals = getArgValueList(a); @@ -193,7 +305,7 @@ public class ArgValuesMap } public ArgValue getClosestNextArgValueOfArg(ArgValue thisAv, Arg a, - boolean withinType) + boolean withinTypes) { // this looks for the *next* arg that *might* be referring back to // a thisAv. Such an arg would have no subValues (if it does it should @@ -215,14 +327,14 @@ public class ArgValuesMap } // check if withinType this closestAv doesn't belong to the next primary arg - // of this type - if (withinType && closestAv != null) + // of this type. Checking for *any* shared type. + if (withinTypes && closestAv != null) { int nextPrimaryArgOfSameTypeIndex = Integer.MAX_VALUE; for (Arg tmpA : this.getArgKeys()) { // interested in Opt.PRIMARY args of the same type - if (tmpA.getType() == a.getType() && tmpA.hasOption(Opt.PRIMARY)) + if (tmpA.sharesType(a) && tmpA.hasOption(Opt.PRIMARY)) { for (ArgValue tmpAv : getArgValueList(tmpA)) { @@ -237,7 +349,7 @@ public class ArgValuesMap } if (nextPrimaryArgOfSameTypeIndex < closestAv.getArgIndex()) { - // looks licke closestAv actually belongs to a different primary Arg + // looks like closestAv actually belongs to a different primary Arg return null; } } @@ -370,33 +482,32 @@ public class ArgValuesMap public String getFromSubValArgOrPref(ArgValue av, Arg a, SubVals sv, String key, String pref, String def) { - return getFromSubValArgOrPref(a, ArgValuesMap.Position.AFTER, av, sv, - key, pref, def); + return getFromSubValArgOrPref(a, Position.AFTER, av, sv, key, pref, + def); } /** * get from following(AFTER), first occurence of (FIRST) or previous (BEFORE) * Arg of type a or subval key or preference pref or default def */ - public String getFromSubValArgOrPref(Arg a, ArgValuesMap.Position pos, - ArgValue av, SubVals sv, String key, String pref, String def) + public String getFromSubValArgOrPref(Arg a, Position pos, ArgValue av, + SubVals sv, String key, String pref, String def) { return getFromSubValArgOrPrefWithSubstitutions(null, a, pos, av, sv, key, pref, def); } public String getFromSubValArgOrPrefWithSubstitutions(ArgParser ap, Arg a, - ArgValuesMap.Position pos, ArgValue av, SubVals sv, String key, - String pref, String def) + Position pos, ArgValue av, SubVals sv, String key, String pref, + String def) { - return getFromSubValArgOrPrefWithSubstitutionsWithinType(ap, a, pos, av, - sv, key, pref, def, true); + return getFromSubValArgOrPrefWithSubstitutionsWithinTypes(ap, a, pos, + av, sv, key, pref, def, true); } - public String getFromSubValArgOrPrefWithSubstitutionsWithinType( - ArgParser ap, Arg a, ArgValuesMap.Position pos, ArgValue av, - SubVals sv, String key, String pref, String def, - boolean withinType) + public String getFromSubValArgOrPrefWithSubstitutionsWithinTypes( + ArgParser ap, Arg a, Position pos, ArgValue av, SubVals sv, + String key, String pref, String def, boolean withinTypes) { if (key == null) key = a.getName(); @@ -414,14 +525,14 @@ public class ArgValuesMap && getClosestPreviousArgValueOfArg(av, a) != null) value = getClosestPreviousArgValueOfArg(av, a).getValue(); else if (pos == ArgValuesMap.Position.AFTER - && getClosestNextArgValueOfArg(av, a, withinType) != null) - value = getClosestNextArgValueOfArg(av, a, withinType).getValue(); + && getClosestNextArgValueOfArg(av, a, withinTypes) != null) + value = getClosestNextArgValueOfArg(av, a, withinTypes).getValue(); // look for allstructures subval for Type.STRUCTURE Arg arg = av.getArg(); if (value == null && arg.hasOption(Opt.PRIMARY) - && arg.getType() == Type.STRUCTURE - && !a.hasOption(Opt.PRIMARY) && (a.getType() == Type.STRUCTURE + && arg.hasType(Type.STRUCTURE) && !a.hasOption(Opt.PRIMARY) + && (a.getFirstType() == Type.STRUCTURE // || a.getType() == Type.STRUCTUREIMAGE)) )) { @@ -432,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/bin/argparser/BootstrapArgs.java b/src/jalview/bin/argparser/BootstrapArgs.java index 80e08c5..51f8147 100644 --- a/src/jalview/bin/argparser/BootstrapArgs.java +++ b/src/jalview/bin/argparser/BootstrapArgs.java @@ -160,10 +160,12 @@ public class BootstrapArgs argsOptions.add(opt); } } - Type t = a.getType(); - if (!argsTypes.contains(t)) + for (Type t : a.getTypes()) { - argsTypes.add(t); + if (!argsTypes.contains(t)) + { + argsTypes.add(t); + } } } diff --git a/src/jalview/util/ColorUtils.java b/src/jalview/util/ColorUtils.java index 9ed98bd..24128ea 100644 --- a/src/jalview/util/ColorUtils.java +++ b/src/jalview/util/ColorUtils.java @@ -24,10 +24,9 @@ package jalview.util; -import java.util.Locale; - import java.awt.Color; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.Random; @@ -234,6 +233,12 @@ public class ColorUtils colour = colour.trim(); Color col = null; + + if ("random".equals(colour)) + { + return generateRandomColor(null); + } + try { int value = Integer.parseInt(colour, 16); @@ -259,7 +264,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 } diff --git a/test/jalview/bin/CommandsTest.java b/test/jalview/bin/CommandsTest.java index 42b93a9..c4fbddb 100644 --- a/test/jalview/bin/CommandsTest.java +++ b/test/jalview/bin/CommandsTest.java @@ -190,9 +190,13 @@ public class CommandsTest Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename + "' has no content from '" + cmdLine + "'"); // make sure the successive output files get bigger! - if (lastFile != null) - Assert.assertTrue(Files.size(file.toPath()) > Files - .size(lastFile.toPath())); + if (lastFile != null) { + Assert.assertTrue(Files.size(file.toPath()) > Files.size(lastFile.toPath())); + System.out.println("this file: " + file + " +" + Files.size(file.toPath()) + " greater than " + + Files.size(lastFile.toPath())); + } + // remember it for next file + lastFile = file; } } catch (Exception x) { @@ -227,9 +231,13 @@ public class CommandsTest Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename + "' has no content from '" + cmdLine + "'"); // make sure the successive output files get bigger! - if (lastFile != null) + if (lastFile != null) { Assert.assertTrue(Files.size(file.toPath()) > Files .size(lastFile.toPath())); + System.out.println("this file: "+file+" +"+Files.size(file.toPath()) + " greater than " +Files.size(lastFile.toPath())); + } + // remember it for next file + lastFile = file; } } catch (Exception x) { @@ -278,6 +286,19 @@ public class CommandsTest { testfiles + "/structureimage1.png", testfiles + "/structureimage2.png", testfiles + "/structureimage3.png" } }, + { "--gui --nonews --nosplash --open examples/1gaq.txt --append ./examples/3W5V.pdb "+"--structure examples/1gaq.txt --seqid \"1GAQ|A\" "+"--structureimage "+testfiles+"/1gaq.png --structure examples/3W5V.pdb "+"--seqid \"3W5V|A\" --structureimage "+testfiles+"/3w5v.png --overwrite", + + new String[] { + testfiles+"/1gaq.png",testfiles+"/3w5v.png" + } + }, + { "--headless --noquit --open ./examples/1gaq.txt --append ./examples/3W5V.pdb "+"--structure examples/1gaq.txt --seqid \"1GAQ|A\" "+"--structureimage "+testfiles+"/1gaq.png --structure examples/3W5V.pdb "+"--seqid \"3W5V|A\" --structureimage "+testfiles+"/3w5v.png --overwrite", + + new String[] { + testfiles+"/1gaq.png",testfiles+"/3w5v.png" + } + } + /* */ //