X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fbin%2Fargparser%2FArgValuesMap.java;h=8a28b8780927d0cfc10fd764a44a15bf58e9f3ac;hb=ccc53e88e3260886f5d3bdacc619c0f374be9b8f;hp=cbc6faaa5525a0d594fb374db5889f43a5bbbc1a;hpb=a7474618cc5b839b6b33803f7e992d26b668244d;p=jalview.git
diff --git a/src/jalview/bin/argparser/ArgValuesMap.java b/src/jalview/bin/argparser/ArgValuesMap.java
index cbc6faa..8a28b87 100644
--- a/src/jalview/bin/argparser/ArgValuesMap.java
+++ b/src/jalview/bin/argparser/ArgValuesMap.java
@@ -1,13 +1,40 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see .
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
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;
import java.util.Set;
+import jalview.bin.Cache;
+import jalview.bin.Console;
import jalview.bin.argparser.Arg.Opt;
+import jalview.bin.argparser.Arg.Type;
import jalview.util.FileUtils;
/**
@@ -16,18 +43,29 @@ import jalview.util.FileUtils;
*/
public class ArgValuesMap
{
+ private List argInfoList = new ArrayList<>();
+
protected Map m;
- protected ArgValuesMap()
+ private String linkedId;
+
+ protected ArgValuesMap(String linkedId)
{
+ this.linkedId = linkedId;
this.newMap();
}
- protected ArgValuesMap(Map map)
+ protected ArgValuesMap(String linkedId, Map map)
{
+ this.linkedId = linkedId;
this.m = map;
}
+ public String getLinkedId()
+ {
+ return linkedId;
+ }
+
private Map getMap()
{
return m;
@@ -41,20 +79,13 @@ public class ArgValuesMap
private void newArg(Arg a)
{
if (m == null)
+ {
newMap();
+ }
if (!containsArg(a))
- m.put(a, new ArgValues(a));
- }
-
- protected void addArgValue(Arg a, ArgValue av)
- {
- if (getMap() == null)
- m = new HashMap();
-
- if (!m.containsKey(a))
- m.put(a, new ArgValues(a));
- ArgValues avs = m.get(a);
- avs.addArgValue(av);
+ {
+ m.put(a, new ArgValues(a, this));
+ }
}
public ArgValues getArgValues(Arg a)
@@ -76,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);
@@ -122,6 +259,33 @@ public class ArgValuesMap
return m.keySet();
}
+ public ArgValue getArgValueOfArgWithSubValKey(Arg a, String svKey)
+ {
+ return getArgValueOfArgWithSubValKey(a, svKey, false);
+ }
+
+ public ArgValue getArgValueOfArgWithSubValKey(Arg a, String svKey,
+ boolean last)
+ {
+ ArgValues avs = this.getArgValues(a);
+ if (avs == null)
+ {
+ return null;
+ }
+ List compareAvs = avs.getArgValueList();
+ for (int i = 0; i < compareAvs.size(); i++)
+ {
+ int index = last ? compareAvs.size() - 1 - i : i;
+ ArgValue av = compareAvs.get(index);
+ SubVals sv = av.getSubVals();
+ if (sv.has(svKey) && !sv.get(svKey).equals("false"))
+ {
+ return av;
+ }
+ }
+ return null;
+ }
+
public ArgValue getClosestPreviousArgValueOfArg(ArgValue thisAv, Arg a)
{
ArgValue closestAv = null;
@@ -140,13 +304,16 @@ public class ArgValuesMap
return closestAv;
}
- public ArgValue getClosestNextArgValueOfArg(ArgValue thisAv, Arg a)
+ public ArgValue getClosestNextArgValueOfArg(ArgValue thisAv, Arg a,
+ 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
// specify an id in the subValues so wouldn't need to be guessed).
ArgValue closestAv = null;
int thisArgIndex = thisAv.getArgIndex();
+ if (!containsArg(a))
+ return null;
ArgValues compareAvs = this.getArgValues(a);
int closestNextIndex = Integer.MAX_VALUE;
for (ArgValue av : compareAvs.getArgValueList())
@@ -158,9 +325,39 @@ public class ArgValuesMap
closestAv = av;
}
}
+
+ // check if withinType this closestAv doesn't belong to the next primary arg
+ // 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.sharesType(a) && tmpA.hasOption(Opt.PRIMARY))
+ {
+ for (ArgValue tmpAv : getArgValueList(tmpA))
+ {
+ int tmpArgIndex = tmpAv.getArgIndex();
+ if (tmpArgIndex > thisArgIndex
+ && tmpArgIndex < nextPrimaryArgOfSameTypeIndex)
+ {
+ nextPrimaryArgOfSameTypeIndex = tmpArgIndex;
+ }
+ }
+ }
+ }
+ if (nextPrimaryArgOfSameTypeIndex < closestAv.getArgIndex())
+ {
+ // looks like closestAv actually belongs to a different primary Arg
+ return null;
+ }
+ }
+
return closestAv;
}
+ // TODO this is incomplete and currently unused (fortunately)
public ArgValue[] getArgValuesReferringTo(String key, String value, Arg a)
{
// this looks for the *next* arg that *might* be referring back to
@@ -198,7 +395,16 @@ public class ArgValuesMap
*/
public String getBasename()
{
- return getDirOrBasename(false);
+ return getDirBasenameOrExtension(false, false, false);
+ }
+
+ /*
+ * This method returns the basename of the first --append or --open value.
+ * Used primarily for substitutions in output filenames.
+ */
+ public String getExtension()
+ {
+ return getDirBasenameOrExtension(false, true, false);
}
/*
@@ -207,10 +413,11 @@ public class ArgValuesMap
*/
public String getDirname()
{
- return getDirOrBasename(true);
+ return getDirBasenameOrExtension(true, false, false);
}
- public String getDirOrBasename(boolean dirname)
+ public String getDirBasenameOrExtension(boolean dirname,
+ boolean extension, boolean absoluteDirname)
{
String filename = null;
String appendVal = getValue(Arg.APPEND);
@@ -223,7 +430,11 @@ public class ArgValuesMap
return null;
File file = new File(filename);
- return dirname ? FileUtils.getDirname(file)
+ if (dirname)
+ {
+ return FileUtils.getDirname(file);
+ }
+ return extension ? FileUtils.getExtension(file)
: FileUtils.getBasename(file);
}
@@ -239,4 +450,237 @@ public class ArgValuesMap
}
return false;
}
+
+ /*
+ * ArgInfo is a more straightforward list of arguments and their info
+ */
+
+ public void addArgInfo(Arg arg, String value, SubVals subVals,
+ int argIndex)
+ {
+ argInfoList.add(new ArgInfo(arg, value, subVals, argIndex));
+ }
+
+ public List getArgInfoList()
+ {
+ Collections.sort(argInfoList);
+ return argInfoList;
+ }
+
+ /**
+ * get from following Arg of type a or subval of same name (lowercase)
+ */
+ public String getValueFromSubValOrArg(ArgValue av, Arg a, SubVals sv)
+ {
+ return getFromSubValArgOrPref(av, a, sv, null, null, null);
+ }
+
+ /**
+ * get from following Arg of type a or subval key or preference pref or
+ * default def
+ */
+ public String getFromSubValArgOrPref(ArgValue av, Arg a, SubVals sv,
+ String key, String pref, String 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, 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,
+ Position pos, ArgValue av, SubVals sv, String key, String pref,
+ String def)
+ {
+ return getFromSubValArgOrPrefWithSubstitutionsWithinTypes(ap, a, pos,
+ av, sv, key, pref, def, true);
+ }
+
+ 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();
+ String value = null;
+ if (sv != null && sv.has(key) && sv.get(key) != null)
+ {
+ value = ap == null ? sv.get(key)
+ : sv.getWithSubstitutions(ap, getLinkedId(), key);
+ }
+ else if (containsArg(a))
+ {
+ if (pos == ArgValuesMap.Position.FIRST && getValue(a) != null)
+ value = getValue(a);
+ else if (pos == ArgValuesMap.Position.BEFORE
+ && getClosestPreviousArgValueOfArg(av, a) != null)
+ value = getClosestPreviousArgValueOfArg(av, a).getValue();
+ else if (pos == ArgValuesMap.Position.AFTER
+ && 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.hasType(Type.STRUCTURE) && !a.hasOption(Opt.PRIMARY)
+ && (a.getFirstType() == Type.STRUCTURE
+ // || a.getType() == Type.STRUCTUREIMAGE))
+ ))
+ {
+ ArgValue av2 = getArgValueOfArgWithSubValKey(a,
+ Arg.ALLSTRUCTURES.getName());
+ if (av2 != null)
+ {
+ 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)
+ {
+ value = pref != null ? Cache.getDefault(pref, def) : def;
+ }
+ return value;
+ }
+
+ public boolean getBoolFromSubValOrArg(Arg a, SubVals sv)
+ {
+ return getFromSubValArgOrPref(a, sv, null, null, false);
+ }
+
+ public boolean getFromSubValArgOrPref(Arg a, SubVals sv, String key,
+ String pref, boolean def)
+ {
+ return getFromSubValArgOrPref(a, sv, key, pref, def, false);
+ }
+
+ public boolean getFromSubValArgOrPref(Arg a, SubVals sv, String key,
+ String pref, boolean def, boolean invertPref)
+ {
+ if ((key == null && a == null) || (sv == null && a == null))
+ return false;
+
+ boolean usingArgKey = false;
+ if (key == null)
+ {
+ key = a.getName();
+ usingArgKey = true;
+ }
+
+ String nokey = ArgParser.NEGATESTRING + key;
+
+ // look for key or nokey in subvals first (if using Arg check options)
+ if (sv != null)
+ {
+ // check for true boolean
+ if (sv.has(key) && sv.get(key) != null)
+ {
+ if (usingArgKey)
+ {
+ if (!(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY)))
+ {
+ Console.debug(
+ "Looking for boolean in subval from non-boolean/non-unary Arg "
+ + a.getName());
+ return false;
+ }
+ }
+ return sv.get(key).toLowerCase(Locale.ROOT).equals("true");
+ }
+
+ // check for negative boolean (subval "no..." will be "true")
+ if (sv.has(nokey) && sv.get(nokey) != null)
+ {
+ if (usingArgKey)
+ {
+ if (!(a.hasOption(Opt.BOOLEAN)))
+ {
+ Console.debug(
+ "Looking for negative boolean in subval from non-boolean Arg "
+ + a.getName());
+ return false;
+ }
+ }
+ return !sv.get(nokey).toLowerCase(Locale.ROOT).equals("true");
+ }
+ }
+
+ // check argvalues
+ if (containsArg(a))
+ return getBoolean(a);
+
+ // return preference or default
+ boolean prefVal = pref != null ? Cache.getDefault(pref, def) : false;
+ return pref != null ? (invertPref ? !prefVal : prefVal) : def;
+ }
+
+ public class ArgInfo implements Comparable
+ {
+ private Arg arg;
+
+ private String value;
+
+ private SubVals subVals;
+
+ private int argIndex;
+
+ public ArgInfo(Arg arg, String value, SubVals subVals, int argIndex)
+ {
+ this.arg = arg;
+ this.value = value;
+ this.subVals = subVals;
+ this.argIndex = argIndex;
+ }
+
+ public Arg arg()
+ {
+ return arg;
+ }
+
+ public String value()
+ {
+ return value;
+ }
+
+ public SubVals subVals()
+ {
+ return subVals;
+ }
+
+ public int argIndex()
+ {
+ return argIndex;
+ }
+
+ @Override
+ public int compareTo(ArgInfo ai2)
+ {
+ return Integer.compare(this.argIndex(), ai2.argIndex());
+ }
+ }
+
+ public static enum Position
+ {
+ FIRST, BEFORE, AFTER
+ }
}