JAL-2994 use pattern matches to search for chimera.exe
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 28 May 2018 10:33:18 +0000 (11:33 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 28 May 2018 10:33:18 +0000 (11:33 +0100)
src/ext/edu/ucsf/rbvi/strucviz2/StructureManager.java
src/jalview/util/FileUtils.java
test/jalview/util/FileUtilsTest.java [new file with mode: 0644]

index 09a9713..a52adc5 100644 (file)
@@ -34,9 +34,11 @@ package ext.edu.ucsf.rbvi.strucviz2;
 
 import jalview.bin.Cache;
 import jalview.gui.Preferences;
+import jalview.util.FileUtils;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -934,17 +936,20 @@ public class StructureManager
     }
     else if (os.startsWith("Windows"))
     {
+      /*
+       * typical Windows installation path is
+       * C:\Program Files\Chimera 1.12\bin\chimera.exe
+       */
       for (String root : new String[] { "\\Program Files",
           "C:\\Program Files", "\\Program Files (x86)",
           "C:\\Program Files (x86)" })
       {
-        for (String version : new String[] { "1.11", "1.11.1", "1.11.2",
-            "1.12", "1.12.1", "1.12.2", "1.13" })
-        {
-          pathList.add(root + "\\Chimera " + version + "\\bin\\chimera");
-          pathList.add(
-                  root + "\\Chimera " + version + "\\bin\\chimera.exe");
-        }
+        /*
+         * match a path ending in \bin\chimera or \bin\chimera.exe
+         * back-slash is double escaped - for Java String, and regex pattern
+         */
+        pathList.addAll(FileUtils.findMatchingPaths(
+                ".*\\\\bin\\\\chimera(\\\\.exe)?$", Paths.get(root)));
       }
     }
     else if (os.startsWith("Mac"))
index 1684763..3652448 100644 (file)
@@ -2,6 +2,12 @@ package jalview.util;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Miscellaneous file-related functions
@@ -75,4 +81,42 @@ public final class FileUtils
     return f;
   }
 
+  /**
+   * Answers a (possibly empty) list of file paths found by searching below
+   * <code>from</code> that match the supplied regular expression
+   * <code>pattern</code>. Results may include <code>from</code> itself if it
+   * matches. If an exception occurs it is written to syserr and any results up
+   * to that point are returned. Note that the regular expression match applies
+   * to the whole path of any matched file.
+   * <p>
+   * Because the whole directory tree below <code>from</code> is searched, this
+   * method may be slow if used for a high level directory.
+   * 
+   * <pre>
+   * Example: 
+   *   findMatchingPaths(".*&#47chimera.exe$", Paths.get("C:/Program Files"))
+   * </pre>
+   * 
+   * @param pattern
+   * @param from
+   * @return
+   * @see https://stackoverflow.com/questions/794381/how-to-find-files-that-match-a-wildcard-string-in-java/31685610#comment62441832_31685610
+   */
+  public static List<String> findMatchingPaths(String pattern, Path from)
+  {
+    List<String> matches = new ArrayList<>();
+    PathMatcher pathMatcher = FileSystems.getDefault()
+            .getPathMatcher("regex:" + pattern);
+    try
+    {
+      Files.walk(from).filter(pathMatcher::matches)
+              .forEach(m -> matches.add(m.toString()));
+    } catch (IOException e)
+    {
+      System.err.println(
+              "Error searching for " + pattern + " : " + e.toString());
+    }
+
+    return matches;
+  }
 }
diff --git a/test/jalview/util/FileUtilsTest.java b/test/jalview/util/FileUtilsTest.java
new file mode 100644 (file)
index 0000000..aed9142
--- /dev/null
@@ -0,0 +1,30 @@
+package jalview.util;
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class FileUtilsTest
+{
+  @Test(groups = "Functional")
+  public void testFindMatchingPaths() throws IOException
+  {
+    String expect1 = Paths.get("../jalview/examples/plantfdx.fa")
+            .toString();
+    String expect2 = Paths.get("../jalview/examples/plantfdx.features")
+            .toString();
+    String expect3 = Paths
+            .get("../jalview/examples/testdata/plantfdx.features")
+            .toString();
+
+    List<String> matches = FileUtils.findMatchingPaths(".*/plant.*\\.f.*",
+            Paths.get(".."));
+    assertTrue(matches.contains(expect1));
+    assertTrue(matches.contains(expect2));
+    assertTrue(matches.contains(expect3));
+  }
+}