package jalview.bin.argparser; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import jalview.bin.argparser.Arg.Opt; import jalview.util.FileUtils; public class BootstrapArgs { // only need one private Map> bootstrapArgMap = new HashMap<>(); private Set argFiles = new HashSet<>(); public static BootstrapArgs getBootstrapArgs(String[] args) { List argList = new ArrayList<>(Arrays.asList(args)); return new BootstrapArgs(argList); } private BootstrapArgs(List args) { parse(args, null); } private void parse(List args, File inArgFile) { if (args == null) return; // avoid looping argFiles if (inArgFile != null) { if (argFiles.contains(inArgFile)) { System.err.println( "Looped argfiles detected: '" + inArgFile.getPath() + "'"); return; } argFiles.add(inArgFile); } for (int i = 0; i < args.size(); i++) { String arg = args.get(i); String argName = null; String val = null; if (arg.startsWith(ArgParser.DOUBLEDASH)) { // remove "--" arg = arg.substring(ArgParser.DOUBLEDASH.length()); int equalPos = arg.indexOf(ArgParser.EQUALS); if (equalPos > -1 && ArgParser.argMap.containsKey(arg.substring(0, equalPos))) { argName = arg.substring(0, equalPos); val = arg.substring(equalPos + 1); } // check for boolean prepended by "no" else if (arg.startsWith(ArgParser.NEGATESTRING) && ArgParser.argMap.containsKey( arg.substring(ArgParser.NEGATESTRING.length()))) { argName = arg.substring(ArgParser.NEGATESTRING.length()); val = "false"; } else if (ArgParser.argMap.containsKey(arg)) { argName = arg; val = "true"; } Arg a = ArgParser.argMap.get(argName); if (a == null || !a.hasOption(Opt.BOOTSTRAP)) { // not a valid bootstrap arg continue; } if (a.hasOption(Opt.STRING)) { List vals = null; if (equalPos == -1) { vals = ArgParser.getShellGlobbedFilenameValues(a, args, i + 1); } else { if (a.hasOption(Opt.GLOB)) { vals = FileUtils.getFilenamesFromGlob(val); } else { vals = new ArrayList<>(); vals.add(val); } } addAll(a, vals); if (a == Arg.ARGFILE) { for (String filename : vals) { File argFile = new File(filename); parse(ArgParser.readArgFile(argFile), argFile); } } } else { add(a, val); } } } } public boolean contains(Arg a) { return bootstrapArgMap.containsKey(a); } public List getList(Arg a) { return bootstrapArgMap.get(a); } private List getOrCreateList(Arg a) { List l = getList(a); if (l == null) { l = new ArrayList<>(); putList(a, l); } return l; } private void putList(Arg a, List l) { bootstrapArgMap.put(a, l); } /* * Creates a new list if not used before, * adds the value unless the existing list is non-empty * and the arg is not MULTI (so first expressed value is * retained). */ private void add(Arg a, String s) { List l = getOrCreateList(a); if (a.hasOption(Opt.MULTI) || l.size() == 0) { l.add(s); } } private void addAll(Arg a, List al) { List l = getOrCreateList(a); if (a.hasOption(Opt.MULTI)) { l.addAll(al); } else if (l.size() == 0 && al.size() > 0) { l.add(al.get(0)); } } /* * Retrieves the first value even if MULTI. * A convenience for non-MULTI args. */ public String get(Arg a) { if (!bootstrapArgMap.containsKey(a)) return null; List aL = bootstrapArgMap.get(a); return (aL == null || aL.size() == 0) ? null : aL.get(0); } public boolean getBoolean(Arg a, boolean d) { if (!bootstrapArgMap.containsKey(a)) return d; return Boolean.parseBoolean(get(a)); } public boolean getBoolean(Arg a) { if (!(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY))) { return false; } if (bootstrapArgMap.containsKey(a)) return Boolean.parseBoolean(get(a)); else return a.getDefaultBoolValue(); } }