import java.util.Map;
import java.util.Set;
+import jalview.util.FileUtils;
+
public class ArgParser
{
private static final String NEGATESTRING = "no";
private static enum Opt
{
- BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES, BOOTSTRAP
+ BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES, BOOTSTRAP,
+ GLOB
}
// These bootstrap args are simply parsed before a full parse of arguments and
CLOSE.setOptions(Opt.UNARY, Opt.LINKED);
DEBUG.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
QUIET.setOptions(Opt.UNARY, Opt.MULTI, Opt.BOOTSTRAP);
- ARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP);
+ ARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.GLOB);
}
private final String[] argNames;
}
}
- public static ArgParser parseArgFiles(List<String> argFilenames)
+ public static ArgParser parseArgFiles(List<String> argFilenameGlobs)
+ {
+ List<File> argFiles = new ArrayList<>();
+
+ for (String pattern : argFilenameGlobs)
+ {
+ // I don't think we want to dedup files, making life easier
+ argFiles.addAll(FileUtils.getFilesFromGlob(pattern));
+ }
+
+ return parseArgFileList(argFiles);
+ }
+
+ public static ArgParser parseArgFileList(List<File> argFiles)
{
List<String> argsList = new ArrayList<>();
- for (String argFilename : argFilenames)
+ for (File argFile : argFiles)
{
- File argFile = new File(argFilename);
if (!argFile.exists())
{
- System.err
- .println("--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT)
- + "=\"" + argFilename + "\": File does not exist.");
+ System.err.println(
+ "--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT) + "=\""
+ + argFile.getPath() + "\": File does not exist.");
System.exit(2);
}
try
{
- argsList.addAll(Files.readAllLines(Paths.get(argFilename)));
+ argsList.addAll(Files.readAllLines(Paths.get(argFile.getPath())));
} catch (IOException e)
{
- System.err.println(
- "--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT) + "=\""
- + argFilename + "\": File could not be read.");
+ System.err.println("--"
+ + Arg.ARGFILE.name().toLowerCase(Locale.ROOT) + "=\""
+ + argFile.getPath() + "\": File could not be read.");
System.exit(3);
}
}
// only need one
private static Map<Arg, List<String>> bootstrapArgMap = new HashMap<>();
- private BootstrapArgs(String[] args)
+ public static BootstrapArgs getBootstrapArgs(String[] args)
{
- init(args);
+ return new BootstrapArgs(args);
}
- public static BootstrapArgs getBootstrapArgs(String[] args)
+ private BootstrapArgs(String[] args)
{
- return new BootstrapArgs(args);
+ init(args);
}
private void init(String[] args)
System.exit(0);
}
- if (argparser.isSet(Arg.HEADLESS))
+ if (bootstrapArgs.contains(Arg.HEADLESS))
{
System.setProperty("java.awt.headless", "true");
// new
--- /dev/null
+package jalview.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+
+public class FileUtils
+{
+ /*
+ * Given string glob pattern (see
+ * https://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)
+ * ) return a List of Files that match the pattern.
+ * Note this is a java style glob, not necessarily a bash-style glob, though there are sufficient similarities.
+ */
+ public static List<File> getFilesFromGlob(String pattern)
+ {
+ List<File> files = new ArrayList<>();
+
+ /*
+ * For efficiency of the Files.walkFileTree, let's find the longest path that doesn't need globbing.
+ * We look for the first glob character * { ? and then look for the last File.separator before that.
+ * Then we can reset the path to look at and shorten the globbing pattern.
+ * Relative paths can be used in pattern, which work from the pwd (though these are converted into
+ * full paths in the match).
+ */
+ int firstGlobChar = -1;
+ boolean foundGlobChar = false;
+ for (char c : new char[] { '*', '{', '?' })
+ {
+ if (pattern.indexOf(c) > -1
+ && (pattern.indexOf(c) < firstGlobChar || !foundGlobChar))
+ {
+ firstGlobChar = pattern.indexOf(c);
+ foundGlobChar = true;
+ }
+ }
+ int lastFS = pattern.lastIndexOf(File.separatorChar, firstGlobChar);
+ if (foundGlobChar)
+ {
+ String pS = pattern.substring(0, lastFS + 1);
+ String rest = pattern.substring(lastFS + 1);
+ Path parentDir = Paths.get(pS).toAbsolutePath();
+ if (parentDir.toFile().exists())
+ {
+ try
+ {
+ String glob = "glob:" + parentDir.toString() + File.separator
+ + rest;
+ PathMatcher pm = FileSystems.getDefault().getPathMatcher(glob);
+ int maxDepth = rest.contains("**") ? Integer.MAX_VALUE
+ : (int) (rest.chars()
+ .filter(ch -> ch == File.separatorChar).count())
+ + 1;
+ Files.walkFileTree(parentDir,
+ EnumSet.of(FileVisitOption.FOLLOW_LINKS), maxDepth,
+ new SimpleFileVisitor<Path>()
+ {
+ @Override
+ public FileVisitResult visitFile(Path path,
+ BasicFileAttributes attrs) throws IOException
+ {
+ if (pm.matches(path))
+ {
+ files.add(path.toFile());
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(Path file,
+ IOException exc) throws IOException
+ {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ else
+ {
+ // no wildcards
+ File f = new File(pattern);
+ if (f.exists())
+ {
+ files.add(f);
+ }
+ }
+
+ return files;
+ }
+}
\ No newline at end of file
public String getAnnotLabel()
{
StringBuilder label = new StringBuilder("pAE Matrix");
- if (this.getReferenceSeq() != null)
- label.append(":").append(this.getReferenceSeq().getDisplayId(false));
+ // if (this.getReferenceSeq() != null)
+ // label.append(":").append(this.getReferenceSeq().getDisplayId(false));
return label.toString();
}