View Javadoc
1   package edu.jiangxin.apktoolbox.utils;
2   
3   import org.apache.logging.log4j.LogManager;
4   import org.apache.logging.log4j.Logger;
5   
6   import java.awt.*;
7   import java.io.File;
8   import java.io.IOException;
9   import java.util.Arrays;
10  import java.util.List;
11  
12  /**
13   * Cross-platform helper for revealing a file or folder in the native file-manager.
14   */
15  public final class RevealFileUtils {
16      private static final Logger logger = LogManager.getLogger(RevealFileUtils.class.getSimpleName());
17  
18      private RevealFileUtils() {}
19  
20      /**
21       * Opens the system file-manager and highlights the supplied file or folder.
22       *
23       * @param file the file or folder to reveal
24       * @throws IOException if the file does not exist or the platform command fails
25       */
26      public static void revealFile(File file) {
27          if (file == null) {
28              logger.error("revealFile failed: file is null");
29              return;
30          }
31          if (!file.exists()) {
32              logger.error("revealFile failed: file does not exist: {}", file.getPath());
33              return;
34          }
35  
36          String os   = System.getProperty("os.name").toLowerCase();
37          String path = file.getAbsolutePath();
38  
39          List<String> cmd;
40  
41          //https://stackoverflow.com/questions/32314645/java-processbuilder-command-arguments-with-spaces-and-double-quotes-fails
42          //TODO: test with spaces and special characters in path
43  
44          if (os.contains("win")) {
45              // Pass the whole flag as one token, already quoted.
46              cmd = Arrays.asList("explorer.exe", "/select", path);
47  
48          } else if (os.contains("mac")) {
49              cmd = Arrays.asList("open", "-R", path);   // open handles quoting internally
50  
51          } else {
52              // Linux – DBus interface wants file:// URI, properly encoded
53              String uri = "file://" + file.toURI().getRawPath();
54              if (file.isDirectory()) {
55                  // Fallback: simply open the directory
56                  cmd = Arrays.asList("xdg-open", path);
57              } else {
58                  cmd = Arrays.asList(
59                          "dbus-send",
60                          "--session",
61                          "--dest=org.freedesktop.FileManager1",
62                          "--type=method_call",
63                          "/org/freedesktop/FileManager1",
64                          "org.freedesktop.FileManager1.ShowItems",
65                          "array:string:\"" + uri + "\"",
66                          "string:\"\""
67                  );
68              }
69          }
70          logger.info("revealFile cmd: {}", cmd);
71  
72          try {
73              new ProcessBuilder(cmd).start();
74          } catch (IOException e) {
75              logger.error("revealFile failed: {}", e.getMessage());
76          }
77      }
78  
79      public static void revealDirectory(File file) {
80          if (file == null) {
81              logger.error("revealDirectory failed: file is null");
82              return;
83          }
84          if (!file.exists()) {
85              logger.error("revealDirectory failed: file does not exist: {}", file.getPath());
86              return;
87          }
88          if (file.isDirectory()) {
89              try {
90                  Desktop.getDesktop().open(file);
91              } catch (IOException e) {
92                  logger.error("revealDirectory failed: {}", e.getMessage());
93              }
94          }
95      }
96  }