From 711280fcae06fa1a707c7445a3931fa9572e960b Mon Sep 17 00:00:00 2001 From: ipolevoy Date: Thu, 13 Dec 2018 22:29:09 -0600 Subject: [PATCH] #813 Implement ability to create and delete directories recursively --- .../main/java/org/javalite/common/Util.java | 77 +++++++++++++++++++ .../java/org/javalite/common/UtilTest.java | 26 ++++++- 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/javalite-common/src/main/java/org/javalite/common/Util.java b/javalite-common/src/main/java/org/javalite/common/Util.java index 852178cf1..dc19a1922 100644 --- a/javalite-common/src/main/java/org/javalite/common/Util.java +++ b/javalite-common/src/main/java/org/javalite/common/Util.java @@ -16,6 +16,8 @@ package org.javalite.common; import java.io.*; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; import java.util.*; /** @@ -525,4 +527,79 @@ public static Properties readProperties(String fileOrResource) throws IOExceptio } return props; } + + + + /** + * Creates directories recursively. + * + *

For instance, this:

+ *
+     *     Util.createTree("dir1/dir2/dir3);
+     * 
+ * + * will create "dir1/dir2/dir2". + * + *

+ * If a directory already exists, it will be silently ignored. + *

+ * + *

+ * + *

+ * NOTE: Use '/' as the path separator on *nix and Windows. + *

+ * + * @param path a list of directories where each is a sub-directory of a previous. + * + */ + public static void createTree(Path path) throws IOException { + + // NOTE, the Paths.get("start", ... others) is super annoying, so implemented with strings in a somewhat hacky way. + // Not happy:( + boolean absolute = path.toString().startsWith("/"); + + String[] parts = Util.split(path.toString(), "/"); + for (int i = 0; i < parts.length; i++) { + StringBuilder fullPath = new StringBuilder(); + for(int x = 0; x <= i; x++){ + fullPath.append(parts[x]).append("/"); // should be OK for *nix and Windows + } + File dir = new File((absolute ? "/" : "") + fullPath.toString()); + if(!dir.exists()){ + if(!dir.mkdir()){ + throw new IOException("Failed to create a directory: " + fullPath); + } + } + } + } + + /** + * Deletes a directory recursively with all its contents. Will ignore files and directories if they are disappear during the oprtation. + * + * @param directory directory to delete. + */ + public static void recursiveDelete(Path directory) throws IOException { + + try { + Files.walkFileTree(directory, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws java.io.IOException { + try { + Files.delete(file); + } catch (NoSuchFileException ignore) {} + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, java.io.IOException exc) throws java.io.IOException { + try{ + Files.delete(dir); + }catch (NoSuchFileException ignore){} + return FileVisitResult.CONTINUE; + } + }); + } catch (NoSuchFileException ignore) {} + + } } diff --git a/javalite-common/src/test/java/org/javalite/common/UtilTest.java b/javalite-common/src/test/java/org/javalite/common/UtilTest.java index 1feaafb5c..a48e09918 100644 --- a/javalite-common/src/test/java/org/javalite/common/UtilTest.java +++ b/javalite-common/src/test/java/org/javalite/common/UtilTest.java @@ -18,7 +18,9 @@ package org.javalite.common; import java.io.ByteArrayInputStream; +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; @@ -133,7 +135,7 @@ public void testEmptyArray() { @Test public void testEmptyCollection() { a(Util.empty((Collection) null)).shouldBeTrue(); - a(Util.empty(new ArrayList())).shouldBeTrue(); + a(Util.empty(new ArrayList())).shouldBeTrue(); a(Util.empty(Collections.list("Hello"))).shouldBeFalse(); } @@ -228,4 +230,26 @@ public void testJoinAndRepeat() { Util.joinAndRepeat(sb, "na", ", ", 16); the(sb.toString()).shouldBeEqual("na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na"); } + + @Test + public void shouldCreateAndDeleteDirectories() throws IOException { + + String root = "target/dir1"; + + Util.recursiveDelete(Paths.get(root)); // will ignore that the directory does not exist yet + the(Paths.get(root).toFile().exists()).shouldBeFalse(); + + Util.createTree(Paths.get(root + "/dir2/dir3")); + the(Paths.get("target/dir1/dir2/dir3").toFile().exists()).shouldBeTrue(); + Util.recursiveDelete(Paths.get("target/dir1/dir2")); + the(Paths.get("target/dir1/dir2").toFile().exists()).shouldBeFalse(); + the(Paths.get("target/dir1/dir2/dir3").toFile().exists()).shouldBeFalse(); + the(Paths.get("target/dir1/").toFile().exists()).shouldBeTrue(); + + //test absolute path + String curDir = new File(".").getCanonicalPath(); + Util.createTree( Paths.get(curDir + "/target/dir4")); + the(Paths.get(curDir + "/target/dir4").toFile().exists()).shouldBeTrue(); + } + }