JAL-629 Fix --headless for new args. Fix progressbar for non-headless commands. Add...
[jalview.git] / src / jalview / bin / ArgParser.java
index cc31f5b..c7527c8 100644 (file)
  */
 package jalview.bin;
 
+import java.io.File;
+import java.io.IOException;
 import java.net.URLDecoder;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -43,9 +47,16 @@ public class ArgParser
 
   private static enum Opt
   {
-    BOOLEAN, STRING, UNARY, MULTI, LINKED, ORDERED, NODUPLICATEVALUES
+    BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES
   }
 
+  // These bootstrap args are simply parsed before a full parse of arguments and
+  // so are accessible at an earlier stage to (e.g.) set debug log leve, provide
+  // a props file (that might set log level), run headlessly, read an argfile
+  // instead of other args.
+  private static final Collection<Arg> bootstrapArgs = new ArrayList(
+          Arrays.asList(Arg.PROPS, Arg.DEBUG, Arg.HEADLESS, Arg.ARGFILE));
+
   public enum Arg
   {
     /*
@@ -61,7 +72,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, DEBUG("d");
+    NOSTRUCTURE, STRUCTURE, IMAGE, QUIT, DEBUG("d"), ARGFILE;
 
     static
     {
@@ -114,6 +125,7 @@ public class ArgParser
       IMAGE.setOptions(Opt.STRING, Opt.LINKED);
       QUIT.setOptions(Opt.UNARY);
       DEBUG.setOptions(Opt.BOOLEAN);
+      ARGFILE.setOptions(Opt.STRING);
     }
 
     private final String[] argNames;
@@ -783,6 +795,8 @@ public class ArgParser
 
     public void parseVals(String item)
     {
+      if (item == null)
+        return;
       if (item.indexOf('[') == 0 && item.indexOf(']') > 1)
       {
         int openBracket = item.indexOf('[');
@@ -934,7 +948,8 @@ public class ArgParser
     {
       if (m == null || !m.containsKey(a))
         return false;
-      return getArgValue(a) != null;
+      return a.hasOption(Opt.STRING) ? getArgValue(a) != null
+              : this.getBoolean(a);
     }
 
     protected boolean hasValue(Arg a, String val)
@@ -1037,9 +1052,6 @@ public class ArgParser
     }
   }
 
-  private static final Collection<Arg> bootstrapArgs = new ArrayList(
-          Arrays.asList(Arg.PROPS, Arg.DEBUG));
-
   public static Map<Arg, String> bootstrapArgs(String[] args)
   {
     Map<Arg, String> bootstrapArgMap = new HashMap<>();
@@ -1070,4 +1082,26 @@ public class ArgParser
     }
     return bootstrapArgMap;
   }
+
+  public static ArgParser parseArgFile(String argFilename)
+  {
+    List<String> argsList = null;
+    File argFile = new File(argFilename);
+    if (!argFile.exists())
+    {
+      System.err.println("--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT)
+              + "=\"" + argFilename + "\": File does not exist.");
+      System.exit(2);
+    }
+    try
+    {
+      argsList = Files.readAllLines(Paths.get(argFilename));
+    } catch (IOException e)
+    {
+      System.err.println("--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT)
+              + "=\"" + argFilename + "\": File could not be read.");
+      System.exit(3);
+    }
+    return new ArgParser((String[]) argsList.toArray());
+  }
 }
\ No newline at end of file