package com.smorales.javalab.business.files; import com.smorales.javalab.business.NotRunnableCodeException; import com.smorales.javalab.business.files.async.Async; import com.smorales.javalab.business.processor.boundary.LabPaths; import com.smorales.javalab.business.processor.boundary.SimpleNode; import com.smorales.javalab.business.processor.boundary.rest.request.TreeNode; import javax.inject.Inject; import java.io.File; import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import static com.smorales.javalab.business.processor.boundary.SimpleNode.Type.FILE; import static com.smorales.javalab.business.processor.boundary.SimpleNode.Type.FOLDER; public class FileManager { @Inject Logger tracer; public Path createTempDir() { try { Path tempDir = Files.createDirectory(Paths.get(LabPaths.HOME.asString() + generateUUID() + File.separator)); tracer.info("Created temp dir: " + tempDir); return tempDir; } catch (IOException e) { tracer.log(Level.SEVERE, e, e::getMessage); throw new NotRunnableCodeException(e); } } private String generateUUID() { return UUID.randomUUID().toString(); } public Path calculatePathForNode(SimpleNode node, List<SimpleNode> simpleNodes) { List<SimpleNode> parents = findParentsForNode(node, simpleNodes); String path = ""; for (SimpleNode p : parents) { String label = p.getLabel(); label = label.replaceAll("\\.", "\\/"); if (p.getType() == FOLDER) { label = label + "/"; } path += label; } String label = (node.getType() == FOLDER) ? node.getLabel().replaceAll("\\.", "\\/") : node.getLabel(); return Paths.get(path, label); } private List<SimpleNode> findParentsForNode(SimpleNode node, List<SimpleNode> simpleNodes) { if (node.getParentId() == null) { return new ArrayList<>(); } List<SimpleNode> parentList = new ArrayList<>(); String parentId = node.getParentId(); while (true) { SimpleNode parentNode = findSimpleNode(new SimpleNode(parentId), simpleNodes); parentList.add(parentNode); if (parentNode.getParentId() == null) { Collections.reverse(parentList); return parentList; } else { parentId = parentNode.getParentId(); } } } public SimpleNode findSimpleNode(SimpleNode toFind, List<SimpleNode> simpleNodes) { return simpleNodes.stream() .filter(s -> s.getId().equals(toFind.getId())) .findFirst().orElseThrow(() -> new NotRunnableCodeException("Can not find node:" + toFind.getId())); } public void createFiles(Path tempDir, List<SimpleNode> simpleNodes) { for (SimpleNode node : simpleNodes) { try { Path pathForNode = this.calculatePathForNode(node, simpleNodes); Path path = Paths.get(tempDir.toString(), pathForNode.toString()); if (node.getType() == FILE) { Files.createDirectories(path.getParent()); Files.createFile(path); Files.write(path, node.getData().getBytes(), StandardOpenOption.CREATE); tracer.info("Created file: " + path); } else if (node.getType() == FOLDER) { Files.createDirectories(path); tracer.info("Created folder(s): " + path); } } catch (IOException e) { tracer.log(Level.SEVERE, e, e::getMessage); throw new NotRunnableCodeException("Error creating file: " + node); } } } public void transformToSimpleList(List<TreeNode> treeNodes, List<SimpleNode> simple) { for (TreeNode node : treeNodes) { String id = node.getId(); SimpleNode.Type type = getTypeOfNode(node); String label = node.getLabel(); String data = node.getData(); String parentId = node.getParentId(); SimpleNode simpleNode = new SimpleNode(id, type, label, data, parentId); simple.add(simpleNode); if (node.getChildren() != null && node.getChildren() != null) { transformToSimpleList(node.getChildren(), simple); } } } private SimpleNode.Type getTypeOfNode(TreeNode node) { return (node.getIcon() != null && node.getIcon().equals("fa-file-text-o")) ? FILE : FOLDER; } @Async public void deleteFolderRecursively(Path path) { Objects.nonNull(path); try { Files.walkFileTree(path, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.deleteIfExists(file); tracer.info("Deleted path: " + file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { if (exc != null) { throw exc; } Files.deleteIfExists(dir); tracer.info("Deleted path: " + dir); return FileVisitResult.CONTINUE; } }); if (path.toFile().exists() && path.toFile().list().length == 0) { path.toFile().delete(); } } catch (IOException e) { tracer.log(Level.SEVERE, e, e::getMessage); throw new NotRunnableCodeException("Error deleting path: " + path.toString()); } } public void printAllFilesInFolder(Path tempDir) { try { Files.walk(tempDir).forEach(filePath -> { if (Files.isRegularFile(filePath)) { System.out.println(filePath); } }); } catch (IOException e) { throw new NotRunnableCodeException("Exception printing files in folder", e); } } public String removeExtension(String path) { return path.substring(0, path.lastIndexOf('.')); } }