JAL-629 bootstrap args and properties. Remember index of args for 'previous structure...
[jalview.git] / src / jalview / bin / ArgParser.java
index 338d130..d150db2 100644 (file)
@@ -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;
@@ -59,7 +60,7 @@ public class ArgParser
     USAGESTATS, OPEN, OPEN2, PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC,
     VSESS, OUTPUT, OUTPUTTYPE, SSANNOTATION, NOTEMPFAC, TEMPFAC,
     TEMPFAC_LABEL, TEMPFAC_DESC, TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP,
-    NOSTRUCTURE, STRUCTURE, IMAGE, QUIT;
+    NOSTRUCTURE, STRUCTURE, IMAGE, QUIT, DEBUG("d");
 
     static
     {
@@ -111,6 +112,7 @@ public class ArgParser
       WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED);
       IMAGE.setOptions(Opt.STRING, Opt.LINKED);
       QUIT.setOptions(Opt.UNARY);
+      DEBUG.setOptions(Opt.BOOLEAN);
     }
 
     private final String[] argNames;
@@ -119,6 +121,8 @@ public class ArgParser
 
     private boolean defaultBoolValue = false;
 
+    private int argIndex = -1;
+
     public String toLongString()
     {
       StringBuilder sb = new StringBuilder();
@@ -201,6 +205,16 @@ public class ArgParser
     {
       return defaultBoolValue;
     }
+
+    private void setArgIndex(int i)
+    {
+      this.argIndex = i;
+    }
+
+    protected int getArgIndex()
+    {
+      return this.argIndex;
+    }
   }
 
   public static class ArgValues
@@ -213,12 +227,16 @@ public class ArgParser
 
     private boolean negated = false;
 
-    private List<String> argsList;
+    private int singleArgIndex = -1;
+
+    private List<Integer> argsIndexes;
+
+    private List<ArgValue> argsList;
 
     protected ArgValues(Arg a)
     {
       this.arg = a;
-      this.argsList = new ArrayList<String>();
+      this.argsList = new ArrayList<ArgValue>();
       this.boolValue = arg.getDefaultBoolValue();
     }
 
@@ -272,8 +290,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  '");
@@ -288,25 +307,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<String>();
+        argsList = new ArrayList<ArgValue>();
       }
-      argsList.add(val);
+      argsList.add(new ArgValue(val, argIndex));
     }
 
     protected boolean hasValue(String val)
@@ -314,14 +332,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<String> getValues()
+    /*
+    protected String getValue()
+    {
+    ArgValue av = getArgValue();
+    return av == null ? null : av.getValue();
+    }
+    */
+
+    protected List<ArgValue> getArgValueList()
     {
       return argsList;
     }
@@ -454,6 +480,7 @@ public class ArgParser
 
     // new style
     Enumeration<String> argE = Collections.enumeration(Arrays.asList(args));
+    int argIndex = 0;
     while (argE.hasMoreElements())
     {
       String arg = argE.nextElement();
@@ -555,7 +582,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))
         {
@@ -675,23 +702,29 @@ public class ArgParser
     return m == null ? null : m.get(a);
   }
 
-  public static List<String> getValues(Map<Arg, ArgValues> m, Arg a)
+  public static List<ArgValue> getArgValueList(Map<Arg, ArgValues> m, Arg a)
   {
     ArgValues av = getArgValues(m, a);
-    return av == null ? null : av.getValues();
+    return av == null ? null : av.getArgValueList();
   }
 
-  public static String getValue(Map<Arg, ArgValues> m, Arg a)
+  public static ArgValue getArgValue(Map<Arg, ArgValues> m, Arg a)
   {
-    List<String> vals = getValues(m, a);
+    List<ArgValue> vals = getArgValueList(m, a);
     return (vals == null || vals.size() == 0) ? null : vals.get(0);
   }
 
+  public static String getValue(Map<Arg, ArgValues> m, Arg a)
+  {
+    ArgValue av = getArgValue(m, a);
+    return av == null ? null : av.getValue();
+  }
+
   public static boolean hasValue(Map<Arg, ArgValues> m, Arg a)
   {
     if (!m.containsKey(a))
       return false;
-    return getValue(m, a) != null;
+    return getArgValue(m, a) != null;
   }
 
   public static boolean getBoolean(Map<Arg, ArgValues> m, Arg a)
@@ -700,9 +733,35 @@ public class ArgParser
     return av == null ? false : av.getBoolean();
   }
 
-  public static SubVal getSubVal(String item)
+  public static SubVals getSubVals(String item)
   {
-    return new SubVal(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;
+    }
   }
 
   /**
@@ -711,50 +770,60 @@ public class ArgParser
    * 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 SubVal
+  public static class SubVals
   {
     private static int NOTSET = -1;
 
-    protected int index = NOTSET;
+    private int index = NOTSET;
 
-    protected String keyName = null;
+    private Map<String, String> subVals = null;
 
-    protected String keyValue = null;
+    private static char SEPARATOR = ';';
 
-    protected String content = null;
+    private String content = null;
 
-    public SubVal(String item)
+    public SubVals(String item)
     {
-      this.parseVal(item);
+      this.parseVals(item);
     }
 
-    public void parseVal(String item)
+    public void parseVals(String item)
     {
       if (item.indexOf('[') == 0 && item.indexOf(']') > 1)
       {
         int openBracket = item.indexOf('[');
         int closeBracket = item.indexOf(']');
-        String indexString = item.substring(openBracket + 1, closeBracket);
+        String subvalsString = item.substring(openBracket + 1,
+                closeBracket);
         this.content = item.substring(closeBracket + 1);
-        int equals = indexString.indexOf('=');
-        if (equals > -1)
+        boolean setIndex = false;
+        for (String subvalString : subvalsString
+                .split(Character.toString(SEPARATOR)))
         {
-          this.keyName = indexString.substring(0, equals);
-          this.keyValue = indexString.substring(equals + 1);
-          this.index = -1;
-        }
-        else
-        {
-          try
+          int equals = subvalString.indexOf('=');
+          if (equals > -1)
           {
-            this.index = Integer.parseInt(indexString);
-          } catch (NumberFormatException e)
+            if (subVals == null)
+              subVals = new HashMap<>();
+            subVals.put(subvalString.substring(0, equals),
+                    subvalString.substring(equals + 1));
+          }
+          else
           {
-            Console.warn("Failed to obtain subvalue or index from '" + item
-                    + "'. Setting index=0 and using content='" + content
-                    + "'.");
+            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
       {
@@ -765,7 +834,60 @@ public class ArgParser
     public boolean notSet()
     {
       // notSet is true if content present but nonsensical
-      return index == NOTSET && keyName == null && keyValue == null;
+      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;
+    }
+  }
+
+  private static final Collection<String> bootstrapArgs = new ArrayList(
+          Arrays.asList("props", "debug"));
+
+  public static Map<String, String> bootstrapArgs(String[] args)
+  {
+    Map<String, String> argMap = new HashMap<>();
+    if (args == null)
+      return argMap;
+    Enumeration<String> 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);
+        }
+        if (bootstrapArgs.contains(argName))
+          argMap.put(argName, val);
+      }
     }
+    return argMap;
   }
 }
\ No newline at end of file