JAL-4277 --mkdirs with cautious refusal for paths with ..
[jalview.git] / src / jalview / util / FileUtils.java
index 9b56c64..983ba75 100644 (file)
@@ -36,6 +36,8 @@ public class FileUtils
           boolean allowSingleFilenameThatDoesNotExist)
   {
     pattern = substituteHomeDir(pattern);
+    String relativePattern = pattern.startsWith(File.separator) ? null
+            : pattern;
     List<File> files = new ArrayList<>();
     /*
      * For efficiency of the Files.walkFileTree(), let's find the longest path that doesn't need globbing.
@@ -60,7 +62,11 @@ public class FileUtils
     {
       String pS = pattern.substring(0, lastFS + 1);
       String rest = pattern.substring(lastFS + 1);
-      Path parentDir = Paths.get(pS).toAbsolutePath();
+      if ("".equals(pS))
+      {
+        pS = ".";
+      }
+      Path parentDir = Paths.get(pS);
       if (parentDir.toFile().exists())
       {
         try
@@ -130,30 +136,43 @@ public class FileUtils
   }
 
   /*
-   * This method returns the basename of the first --open or --opennew value. 
-   * Used primarily for substitutions in output filenames.
+   * This method returns the basename of File file
    */
   public static String getBasename(File file)
   {
+    return getBasenameOrExtension(file, false);
+  }
+
+  /*
+   * This method returns the extension of File file.
+   */
+  public static String getExtension(File file)
+  {
+    return getBasenameOrExtension(file, true);
+  }
+
+  public static String getBasenameOrExtension(File file, boolean extension)
+  {
     if (file == null)
       return null;
 
-    String basename = null;
+    String value = null;
     String filename = file.getName();
     int lastDot = filename.lastIndexOf('.');
     if (lastDot > 0) // don't truncate if starts with '.'
     {
-      basename = filename.substring(0, lastDot);
+      value = extension ? filename.substring(lastDot + 1)
+              : filename.substring(0, lastDot);
     }
     else
     {
-      basename = filename;
+      value = extension ? "" : filename;
     }
-    return basename;
+    return value;
   }
 
   /*
-   * This method returns the dirname of the first --open or --opennew value. 
+   * This method returns the dirname of the first --append or --open value. 
    * Used primarily for substitutions in output filenames.
    */
   public static String getDirname(File file)
@@ -162,18 +181,94 @@ public class FileUtils
       return null;
 
     String dirname = null;
-    try
-    {
-      File p = file.getParentFile();
-      File d = new File(substituteHomeDir(p.getPath()));
-      dirname = d.getCanonicalPath();
-    } catch (IOException e)
+    File p = file.getParentFile();
+    if (p == null)
     {
-      Console.debug(
-              "Exception when getting dirname of '" + file.getPath() + "'",
-              e);
-      dirname = "";
+      p = new File(".");
     }
+    File d = new File(substituteHomeDir(p.getPath()));
+    dirname = d.getPath();
     return dirname;
   }
+
+  public static String convertWildcardsToPath(String value, String wildcard,
+          String dirname, String basename)
+  {
+    if (value == null)
+    {
+      return null;
+    }
+    StringBuilder path = new StringBuilder();
+    int lastFileSeparatorIndex = value.lastIndexOf(File.separatorChar);
+    int wildcardBeforeIndex = value.indexOf(wildcard);
+    if (lastFileSeparatorIndex > wildcard.length() - 1
+            && wildcardBeforeIndex < lastFileSeparatorIndex)
+    {
+      path.append(value.substring(0, wildcardBeforeIndex));
+      path.append(dirname);
+      path.append(value.substring(wildcardBeforeIndex + wildcard.length(),
+              lastFileSeparatorIndex + 1));
+    }
+    else
+    {
+      path.append(value.substring(0, lastFileSeparatorIndex + 1));
+    }
+    int wildcardAfterIndex = value.indexOf(wildcard,
+            lastFileSeparatorIndex);
+    if (wildcardAfterIndex > lastFileSeparatorIndex)
+    {
+      path.append(value.substring(lastFileSeparatorIndex + 1,
+              wildcardAfterIndex));
+      path.append(basename);
+      path.append(value.substring(wildcardAfterIndex + wildcard.length()));
+    }
+    else
+    {
+      path.append(value.substring(lastFileSeparatorIndex + 1));
+    }
+    return path.toString();
+  }
+
+  public static File getParentDir(File file)
+  {
+    if (file == null)
+    {
+      return null;
+    }
+    File parentDir = file.getAbsoluteFile().getParentFile();
+    return parentDir;
+  }
+
+  public static boolean checkParentDir(File file, boolean mkdirs)
+  {
+    if (file == null)
+    {
+      return false;
+    }
+    File parentDir = getParentDir(file);
+    if (parentDir.exists())
+    {
+      // already exists, nothing to do so nothing to worry about!
+      return true;
+    }
+
+    if (!mkdirs)
+    {
+      return false;
+    }
+
+    Path path = file.toPath();
+    for (int i = 0; i < path.getNameCount(); i++)
+    {
+      Path p = path.getName(i);
+      if ("..".equals(p.toString()))
+      {
+        Console.warn("Cautiously not running mkdirs on " + file.toString()
+                + " because the path to be made contains '..'");
+        return false;
+      }
+    }
+
+    return parentDir.mkdirs();
+  }
 }