package restx.common; import com.google.common.base.Function; import com.google.common.eventbus.EventBus; import com.google.common.io.ByteStreams; import restx.common.watch.WatcherServiceLoader; import restx.common.watch.WatcherSettings; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.ExecutorService; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import static com.google.common.io.Files.createParentDirs; /** */ public class MoreFiles { public static final Function<? super Path, ? extends File> pathToFile = new Function<Path, File>() { @Override public File apply(Path input) { return input.toFile(); } }; public static final Function<String, Path> strToPath = new Function<String, Path>() { @Override public Path apply(String input) { return FileSystems.getDefault().getPath(input); } }; public static void delete(Path path) throws IOException { if (path.toFile().isDirectory()) { Files.walkFileTree(path, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { // try to delete the file anyway, even if its attributes // could not be read, since delete-only access is // theoretically possible Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { if (exc == null) { Files.delete(dir); return FileVisitResult.CONTINUE; } else { // directory iteration failed; propagate exception throw exc; } } }); } else { Files.deleteIfExists(path); } } public static Closeable watch(Path dir, EventBus eventBus, ExecutorService executor, WatcherSettings watcherSettings) { return WatcherServiceLoader.getWatcherService().watch(eventBus, executor, dir, watcherSettings); } public static void copyDir(final Path sourceDir, final Path targetDir) throws IOException { Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Path target = targetDir.resolve(sourceDir.relativize(file)); File targetDir = target.getParent().toAbsolutePath().toFile(); if (!targetDir.exists() && !targetDir.mkdirs()) { throw new IOException("can't create directory: `" + targetDir + "`"); } Files.copy(file, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES); return FileVisitResult.CONTINUE; } }); } public static void checkFileExists(String location) { File file = new File(location); if (!file.exists()) { String workingDir = "<unknown location>"; try { workingDir = new File(".").getAbsoluteFile().getCanonicalPath(); } catch (IOException e) { // ignore } throw new IllegalStateException( "couldn't find " + location + " in " + workingDir + "\nCheck your working directory.\n"); } } public static void extractZip(File zip, File toDir) throws IOException { try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zip))) { ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { if (!entry.isDirectory()) { File file = new File(toDir, entry.getName()); createParentDirs(file); Files.copy(zis, file.toPath()); zis.closeEntry(); } } } } }