From 8802d8eb43d9db9be4a9100090f7ca39feefcb10 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Thu, 9 Mar 2023 16:29:19 +0000 Subject: [PATCH] JAL-629 --argfile=glob implemented. Remove reference seq from pAE Matrix annotation label --- src/jalview/bin/ArgParser.java | 47 ++++++--- src/jalview/bin/Jalview.java | 2 +- src/jalview/util/FileUtils.java | 105 ++++++++++++++++++++ .../ws/datamodel/alphafold/PAEContactMatrix.java | 4 +- 4 files changed, 139 insertions(+), 19 deletions(-) create mode 100644 src/jalview/util/FileUtils.java diff --git a/src/jalview/bin/ArgParser.java b/src/jalview/bin/ArgParser.java index 65d0026..3b08013 100644 --- a/src/jalview/bin/ArgParser.java +++ b/src/jalview/bin/ArgParser.java @@ -36,6 +36,8 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import jalview.util.FileUtils; + public class ArgParser { private static final String NEGATESTRING = "no"; @@ -44,7 +46,8 @@ public class ArgParser 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 @@ -124,7 +127,7 @@ public class ArgParser 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; @@ -1031,27 +1034,39 @@ public class ArgParser } } - public static ArgParser parseArgFiles(List argFilenames) + public static ArgParser parseArgFiles(List argFilenameGlobs) + { + List 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 argFiles) { List 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); } } @@ -1063,14 +1078,14 @@ public class ArgParser // only need one private static Map> 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) diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index 87c4ad5..b5def09 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -428,7 +428,7 @@ public class Jalview System.exit(0); } - if (argparser.isSet(Arg.HEADLESS)) + if (bootstrapArgs.contains(Arg.HEADLESS)) { System.setProperty("java.awt.headless", "true"); // new diff --git a/src/jalview/util/FileUtils.java b/src/jalview/util/FileUtils.java new file mode 100644 index 0000000..5bc6570 --- /dev/null +++ b/src/jalview/util/FileUtils.java @@ -0,0 +1,105 @@ +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 getFilesFromGlob(String pattern) + { + List 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() + { + @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 diff --git a/src/jalview/ws/datamodel/alphafold/PAEContactMatrix.java b/src/jalview/ws/datamodel/alphafold/PAEContactMatrix.java index d1a2e9d..cefdbd2 100644 --- a/src/jalview/ws/datamodel/alphafold/PAEContactMatrix.java +++ b/src/jalview/ws/datamodel/alphafold/PAEContactMatrix.java @@ -224,8 +224,8 @@ public class PAEContactMatrix implements ContactMatrixI 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(); } -- 1.7.10.2