JAL-2994 use pattern matches to search for chimera.exe
[jalview.git] / src / jalview / util / FileUtils.java
1 package jalview.util;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.nio.file.FileSystems;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.nio.file.PathMatcher;
9 import java.util.ArrayList;
10 import java.util.List;
11
12 /**
13  * Miscellaneous file-related functions
14  */
15 public final class FileUtils
16 {
17
18   /**
19    * Answers the executable file for the given command, or null if not found or
20    * not executable. The path to the executable is the command name prefixed by
21    * the given folder path, optionally with .exe appended.
22    * 
23    * @param cmd
24    *          command short name, for example hmmbuild
25    * @param binaryPath
26    *          parent folder for the executable
27    * @return
28    */
29   public static File getExecutable(String cmd, String binaryPath)
30   {
31     File file = new File(binaryPath, cmd);
32     if (!file.canExecute())
33     {
34       file = new File(binaryPath, cmd + ".exe");
35       {
36         if (!file.canExecute())
37         {
38           file = null;
39         }
40       }
41     }
42     return file;
43   }
44
45   /**
46    * Answers the path to the folder containing the given executable file, by
47    * searching the PATH environment variable. Answers null if no such executable
48    * can be found.
49    * 
50    * @param cmd
51    * @return
52    */
53   public static String getPathTo(String cmd)
54   {
55     String paths = System.getenv("PATH");
56     // backslash is to escape regular expression argument
57     for (String path : paths.split("\\" + File.pathSeparator))
58     {
59       if (getExecutable(cmd, path) != null)
60       {
61         return path;
62       }
63     }
64     return null;
65   }
66
67   /**
68    * A convenience method to create a temporary file that is deleted on exit of
69    * the JVM
70    * 
71    * @param prefix
72    * @param suffix
73    * @return
74    * @throws IOException
75    */
76   public static File createTempFile(String prefix, String suffix)
77           throws IOException
78   {
79     File f = File.createTempFile(prefix, suffix);
80     f.deleteOnExit();
81     return f;
82   }
83
84   /**
85    * Answers a (possibly empty) list of file paths found by searching below
86    * <code>from</code> that match the supplied regular expression
87    * <code>pattern</code>. Results may include <code>from</code> itself if it
88    * matches. If an exception occurs it is written to syserr and any results up
89    * to that point are returned. Note that the regular expression match applies
90    * to the whole path of any matched file.
91    * <p>
92    * Because the whole directory tree below <code>from</code> is searched, this
93    * method may be slow if used for a high level directory.
94    * 
95    * <pre>
96    * Example: 
97    *   findMatchingPaths(".*&#47chimera.exe$", Paths.get("C:/Program Files"))
98    * </pre>
99    * 
100    * @param pattern
101    * @param from
102    * @return
103    * @see https://stackoverflow.com/questions/794381/how-to-find-files-that-match-a-wildcard-string-in-java/31685610#comment62441832_31685610
104    */
105   public static List<String> findMatchingPaths(String pattern, Path from)
106   {
107     List<String> matches = new ArrayList<>();
108     PathMatcher pathMatcher = FileSystems.getDefault()
109             .getPathMatcher("regex:" + pattern);
110     try
111     {
112       Files.walk(from).filter(pathMatcher::matches)
113               .forEach(m -> matches.add(m.toString()));
114     } catch (IOException e)
115     {
116       System.err.println(
117               "Error searching for " + pattern + " : " + e.toString());
118     }
119
120     return matches;
121   }
122 }