JAL-4353 Preserve the user given 'linkedId' with ArgValue, to help with deciding...
[jalview.git] / src / jalview / bin / argparser / ArgValues.java
index 0be7768..55e1211 100644 (file)
@@ -1,16 +1,38 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.bin.argparser;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import jalview.bin.Console;
 import jalview.bin.argparser.Arg.Opt;
+import jalview.bin.argparser.Arg.Type;
 
 public class ArgValues
 {
-  protected static final String ID = "id";
+  public static final String ID = "id";
 
   private Arg arg;
 
@@ -20,6 +42,10 @@ public class ArgValues
 
   private boolean negated = false;
 
+  private boolean setByWildcard = false;
+
+  private String givenLinkedId = null;
+
   private int boolIndex = -1;
 
   private List<Integer> argsIndexes;
@@ -28,11 +54,29 @@ public class ArgValues
 
   private Map<String, ArgValue> idMap = new HashMap<>();
 
-  protected ArgValues(Arg a)
+  private ArgValuesMap avm;
+
+  /*
+   * Type type is only really used by --help-type
+   */
+  private Type type = null;
+
+  protected ArgValues(Arg a, ArgValuesMap avm)
   {
     this.arg = a;
     this.argValueList = new ArrayList<ArgValue>();
     this.boolValue = arg.getDefaultBoolValue();
+    this.avm = avm;
+  }
+
+  protected boolean setByWildcard()
+  {
+    return setByWildcard;
+  }
+
+  protected void setSetByWildcard(boolean b)
+  {
+    setByWildcard = b;
   }
 
   public Arg arg()
@@ -40,6 +84,17 @@ public class ArgValues
     return arg;
   }
 
+  protected void setType(Type t)
+  {
+    if (this.arg().hasOption(Opt.HASTYPE))
+      this.type = t;
+  }
+
+  public Type getType()
+  {
+    return type;
+  }
+
   protected int getCount()
   {
     return argCount;
@@ -50,8 +105,11 @@ public class ArgValues
     argCount++;
   }
 
-  protected void setNegated(boolean b)
+  protected void setNegated(boolean b, boolean beingSetByWildcard)
   {
+    // don't overwrite a wildcard set boolean with a non-wildcard set boolean
+    if (boolIndex >= 0 && !this.setByWildcard && beingSetByWildcard)
+      return;
     this.negated = b;
   }
 
@@ -60,10 +118,17 @@ public class ArgValues
     return this.negated;
   }
 
-  protected void setBoolean(boolean b, int i)
+  protected void setBoolean(Type t, boolean b, int i,
+          boolean beingSetByWildcard, String givenLinkedId)
   {
+    this.setType(t);
+    // don't overwrite a wildcard set boolean with a non-wildcard set boolean
+    if (boolIndex >= 0 && !this.setByWildcard && beingSetByWildcard)
+      return;
     this.boolValue = b;
     this.boolIndex = i;
+    this.setSetByWildcard(beingSetByWildcard);
+    this.givenLinkedId = givenLinkedId;
   }
 
   protected boolean getBoolean()
@@ -85,43 +150,49 @@ public class ArgValues
     if (arg.hasOption(Opt.STRING))
     {
       sb.append("Values:");
-      boolean first = true;
-      for (ArgValue av : argValueList)
-      {
-        String v = av.getValue();
-        if (!first)
-          sb.append(",");
-        sb.append("\n  '");
-        sb.append(v).append("'");
-        first = false;
-      }
+      sb.append("'")
+              .append(String
+                      .join("',\n  '",
+                              argValueList.stream().map(av -> av.getValue())
+                                      .collect(Collectors.toList())))
+              .append("'");
       sb.append("\n");
     }
     sb.append("Count: ").append(argCount).append("\n");
     return sb.toString();
   }
 
-  protected void addValue()
+  protected void addValue(Type type, String val, int argIndex,
+          boolean wildcard, String givenLinkedId)
   {
-    addValue(null, -1);
+    addArgValue(new ArgValue(arg(), type, val, argIndex, wildcard,
+            givenLinkedId, avm.getLinkedId()), wildcard);
   }
 
-  protected void addValue(String val, int argIndex)
+  protected void addValue(SubVals sv, Type type, String content,
+          int argIndex, boolean wildcard, String givenLinkedId)
   {
-    addArgValue(new ArgValue(val, argIndex));
+    addArgValue(new ArgValue(arg(), sv, type, content, argIndex, wildcard,
+            givenLinkedId, avm.getLinkedId()), wildcard);
   }
 
-  protected void addArgValue(ArgValue av)
+  protected void addArgValue(ArgValue av, boolean beingSetByWildcard)
   {
-    if ((!arg.hasOption(Opt.MULTI) && argValueList.size() > 0)
-            || (arg.hasOption(Opt.NODUPLICATEVALUES)
-                    && argValueList.contains(av.getValue())))
+    // allow a non-wildcard value to overwrite a wildcard set single value
+    boolean overwrite = !arg.hasOption(Opt.MULTIVALUE) && setByWildcard
+            && !beingSetByWildcard;
+    if ((!arg.hasOption(Opt.MULTIVALUE) && argValueList.size() > 0)
+            && !overwrite)
       return;
-    if (argValueList == null)
+    if (arg.hasOption(Opt.NODUPLICATEVALUES)
+            && this.containsValue(av.getValue()))
+      return;
+    // new or overwrite if single valued
+    if (argValueList == null || overwrite)
     {
       argValueList = new ArrayList<ArgValue>();
     }
-    SubVals sv = ArgParser.getSubVals(av.getValue());
+    SubVals sv = new SubVals(av.getValue());
     if (sv.has(ID))
     {
       String id = sv.get(ID);
@@ -129,6 +200,7 @@ public class ArgValues
       idMap.put(id, av);
     }
     argValueList.add(av);
+    this.setSetByWildcard(beingSetByWildcard);
   }
 
   protected boolean hasValue(String val)
@@ -138,7 +210,7 @@ public class ArgValues
 
   protected ArgValue getArgValue()
   {
-    if (arg.hasOption(Opt.MULTI))
+    if (arg.hasOption(Opt.MULTIVALUE))
       Console.warn("Requesting single value for multi value argument");
     return argValueList.size() > 0 ? argValueList.get(0) : null;
   }
@@ -157,4 +229,28 @@ public class ArgValues
   {
     return idMap.get(id);
   }
+
+  private boolean containsValue(String v)
+  {
+    if (argValueList == null)
+      return false;
+    for (ArgValue av : argValueList)
+    {
+      String val = av.getValue();
+      if (v == null && val == null)
+        return true;
+      if (v == null)
+        continue;
+      if (v.equals(val))
+        return true;
+    }
+    return false;
+  }
+
+  public boolean setByWildcardLinkedId()
+  {
+    // looking for deliberately user set wildcard
+    return this.setByWildcard && this.givenLinkedId != null;
+  }
+
 }
\ No newline at end of file