From 4fbd297386ae196ea39a051eac1952db2b8db735 Mon Sep 17 00:00:00 2001 From: Kristopher Guzman Date: Wed, 24 Feb 2016 23:47:01 -0500 Subject: [PATCH] Added IronFileFilter, OSDetection, and CmdExecutor. Added feature for tagging files and retrieving tags from files using the tool bar and the tree view. Can execute commands in shell, and detect operation system. --- src/main/java/CmdExecutor.java | 48 ++++++++ src/main/java/Controller.java | 44 ++++++- src/main/java/FileTreeItem.java | 10 +- src/main/java/FolderViewManager.java | 178 ++++++++++++++++++++++++--- src/main/java/IronFile.java | 5 + src/main/java/IronFileFilter.java | 35 ++++++ src/main/java/OSDetection.java | 42 +++++++ src/main/resources/StartPage.fxml | 2 +- 8 files changed, 340 insertions(+), 24 deletions(-) create mode 100644 src/main/java/CmdExecutor.java create mode 100644 src/main/java/IronFileFilter.java create mode 100644 src/main/java/OSDetection.java diff --git a/src/main/java/CmdExecutor.java b/src/main/java/CmdExecutor.java new file mode 100644 index 0000000..1bcecf0 --- /dev/null +++ b/src/main/java/CmdExecutor.java @@ -0,0 +1,48 @@ +package main.java; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * Created by kristopherguzman on 2/19/16. + */ +public class CmdExecutor { + + public CmdExecutor() { } + + public String run(String cmd) throws IOException { + + System.out.println("executing command: " + cmd); + + + String[] args = new String[] {"sh", "-c", "cd / && " + cmd}; + Process process = Runtime.getRuntime().exec(args); + BufferedReader outputReader = new BufferedReader(new InputStreamReader(process.getInputStream())); //efficiently reads chars + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + + String line = outputReader.readLine(); + String error = errorReader.readLine(); + + System.out.println("Below is command output: \n "); + while(line != null) { + + System.out.println("cmd output: " + line); + line = outputReader.readLine(); + + } + + while(error != null) { + + System.out.println("error output: " + error); + error = errorReader.readLine(); + + } + + outputReader.close(); + errorReader.close(); + return null; + + } + +} diff --git a/src/main/java/Controller.java b/src/main/java/Controller.java index f9da16a..6bbb6a6 100644 --- a/src/main/java/Controller.java +++ b/src/main/java/Controller.java @@ -1,5 +1,11 @@ package main.java; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.event.Event; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.MenuItem; @@ -8,6 +14,7 @@ import javafx.scene.control.TreeView; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; import sun.misc.Resource; import sun.reflect.generics.tree.Tree; @@ -26,14 +33,45 @@ public class Controller{ @FXML private MenuItem fileExit; @FXML private MenuItem editPreferences; @FXML private TreeView dirTree; + @FXML private MenuItem toolsTagFiles; @FXML private ResourceBundle resources; @FXML private void initialize() { - FolderViewManager manager = new FolderViewManager(dirTree); // 2 statements in 1 line is best + final FolderViewManager manager = new FolderViewManager(dirTree); // 2 statements in 1 line is best IronFile[] hardDrives = IronFile.listRoots(); // an array of hard drives manager.setRootDirectory(hardDrives); -// IronFile homeDir = new IronFile(System.getProperty("user.home")); // use this for specific directory -// manager.setRootDirectory(homeDir); + + dirTree.setOnMouseClicked(new EventHandler() { + + @Override + public void handle(MouseEvent args) { + + ObservableList> selectedItems = dirTree.getSelectionModel().getSelectedItems(); + + manager.setSelectedFiles(selectedItems); + + } + + }); + + /** + Testing tagging. Be careful with this, tag removal is not implemented yet. + */ + toolsTagFiles.setOnAction(new EventHandler() { + + @Override + public void handle(ActionEvent event) { + + + //manager.setFileAttrForSelected(); + manager.getFileAttrForSelected(); + + } + + + }); + + } } diff --git a/src/main/java/FileTreeItem.java b/src/main/java/FileTreeItem.java index 4b9eaa5..ef1aa5b 100644 --- a/src/main/java/FileTreeItem.java +++ b/src/main/java/FileTreeItem.java @@ -21,7 +21,7 @@ public FileTreeItem(IronFile rootFile) { @Override public ObservableList> getChildren() { - if (isFirstTimeChildren) { + if (isFirstTimeChildren) { //if children of node have not been created, then do so isFirstTimeChildren = false; super.getChildren().setAll(buildChildren(this)); } @@ -39,12 +39,18 @@ public boolean isLeaf() { } private ObservableList buildChildren(TreeItem ironTreeItem) { IronFile f = ironTreeItem.getValue(); + + System.out.println("file's parent: " + f.getParent()); + if (f != null && f.isDirectory()) { IronFile[] files = f.listFiles(); if (files != null) { ObservableList children = FXCollections.observableArrayList(); + for (IronFile childFile : files) { - children.add(new FileTreeItem(childFile)); + if(childFile.filter.accept(childFile, childFile.getName())) { + children.add(new FileTreeItem(childFile)); + } } return children; } diff --git a/src/main/java/FolderViewManager.java b/src/main/java/FolderViewManager.java index 962308c..08a5ef8 100644 --- a/src/main/java/FolderViewManager.java +++ b/src/main/java/FolderViewManager.java @@ -1,51 +1,193 @@ package main.java; +import javafx.collections.ObservableList; +import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.attribute.UserDefinedFileAttributeView; +import java.util.ArrayList; +import java.util.List; + /** This class handles manipulation of the Folder View. This includes directory searches, displaying directories, and all things directly changing the Folder View. - Additionally, this class extends SimpleFileVisitor which uses java 8. - - @author kristopherguzman + @author Kristopher Guzman kristopherguz@gmail.com @author Brian Patino patinobrian@gmail.com */ public class FolderViewManager { + + //private IronFileVisitor ironVisitor; // might be used later private final Image hddIcon = new Image("/main/resources/icons/hdd.png"); -// private IronFileVisitor ironVisitor; // might be used later private TreeView view; + private CmdExecutor command; + private List> selectedFiles; public FolderViewManager(TreeView dirTree) { /*ironVisitor = new IronFileVisitor(); // save this for later ironVisitor.setRoot(new TreeItem<>());*/ // save this for later + + OSDetection.getOS(); view = dirTree; + command = new CmdExecutor(); + } - /** - * Sets the root directory of the file browser to the specified folder. - * - * @param file root folder/file to start browser view - **/ - public void setRootDirectory(IronFile file) { - FileTreeItem rootItem = new FileTreeItem(file); - view.setRoot(rootItem); - } - /** - * Overloaded method that sets a collection of folders/files as file browser view. - * - * @param hardDrives a collection of hard drives to being from root - * */ + public void setRootDirectory(IronFile[] hardDrives) { view.setRoot(new FileTreeItem(new IronFile(""))); // needs a blank file as root for (IronFile hdd : hardDrives) { + System.out.println(hdd.getName()); FileTreeItem diskTreeItem = new FileTreeItem(hdd); diskTreeItem.setGraphic(new ImageView(hddIcon)); view.getRoot().getChildren().add(diskTreeItem); } view.setShowRoot(false); // hide the blank file } + + public void setSelectedFiles(List> files) { + + selectedFiles = files; + + } + + public void setFileAttrForSelected() { + + for(TreeItem item : selectedFiles) { + + setFileAttr(item.getValue(), "test_attr_key", "test_attr_value"); + + } + + } + + public void getFileAttrForSelected() { + + for(TreeItem item : selectedFiles) { + + getFileAttr(item.getValue(), "test_attr_key"); + + } + + } + + public void setFileAttr(IronFile file, String key, String value) { + + if(OSDetection.OSType == OSDetection.OS.WINDOWS) { + + try { + + UserDefinedFileAttributeView view = Files.getFileAttributeView(file.toPath(), UserDefinedFileAttributeView.class); + + //might want to give unique prefix to tag keys to avoid collision with system metadata + view.write(key, Charset.defaultCharset().encode(value)); + + } catch(IOException e) { e.printStackTrace(); } + + } else if(OSDetection.OSType == OSDetection.OS.MAC) { + + String option = ""; + + if(file.isDirectory()) { + option = "-r"; + } + + + String cmd = "xattr -w " + option + " " + key + " " + value + " " + file.getAbsolutePath(); + + try { + + String output = command.run(cmd); + + } catch(IOException e) { e.printStackTrace(); } + + + } + + } + + public String getFileAttr(IronFile file, String key) { + + if(OSDetection.OSType == OSDetection.OS.WINDOWS) { + + try { + UserDefinedFileAttributeView view = Files.getFileAttributeView(file.toPath(), UserDefinedFileAttributeView.class); + + ByteBuffer buf = ByteBuffer.allocate(view.size(key)); + view.read(key, buf); + buf.flip(); + + return Charset.defaultCharset().decode(buf).toString(); + + } catch(IOException e) { e.printStackTrace(); } + + } else if(OSDetection.OSType == OSDetection.OS.MAC) { + + System.out.println("file path: " + file.getAbsolutePath()); + + String option = ""; + + if(file.isDirectory()) { + //option = "-r"; + } + + + String cmd = "xattr -p " + option + " " + key + " " + file.getAbsolutePath(); //then append the attr command + + try { + + String output = command.run(cmd); + + } catch(IOException e) { e.printStackTrace(); } + + } + + return null; + + } + + public String removeFileAttr(IronFile file, String key) { + + if(OSDetection.OSType == OSDetection.OS.WINDOWS) { + + try { + + return (String) Files.getAttribute(file.toPath(), key); + + } catch(IOException e) { e.printStackTrace(); } + + } else if(OSDetection.OSType == OSDetection.OS.MAC) { + + System.out.println("file path: " + file.getAbsolutePath()); + + String option = ""; + + if(file.isDirectory()) { + //option = "-r"; + } + + + String cmd = "xattr -p " + option + " " + key + " " + file.getAbsolutePath(); //then append the attr command + + try { + + String output = command.run(cmd); + + } catch(IOException e) { e.printStackTrace(); } + + } + + return null; + + } + } diff --git a/src/main/java/IronFile.java b/src/main/java/IronFile.java index 45c3037..ce9d6f3 100644 --- a/src/main/java/IronFile.java +++ b/src/main/java/IronFile.java @@ -7,15 +7,20 @@ * This class extends the java File class and returns the filename for toString() */ public class IronFile extends File { + private boolean isRoot = true; + public IronFileFilter filter; public IronFile(String pathname) { super(pathname); isRoot = (getParent() == null); + filter = new IronFileFilter(); } public IronFile(File file) { super(file.getPath()); isRoot = (getParent() == null); + filter = new IronFileFilter(); + } @Override diff --git a/src/main/java/IronFileFilter.java b/src/main/java/IronFileFilter.java new file mode 100644 index 0000000..6488872 --- /dev/null +++ b/src/main/java/IronFileFilter.java @@ -0,0 +1,35 @@ +package main.java; + +import java.io.FilenameFilter; +import java.io.File; +import java.nio.file.Files; + +/** + * Created by kristopherguzman on 2/19/16. + */ +public class IronFileFilter implements FilenameFilter { + + public boolean accept(File file, String name) { + + boolean hidden = false; + boolean isSymbolic = false; + boolean isRegularFile = false; + + try { + + hidden = Files.isHidden(file.toPath()); + isSymbolic = Files.isSymbolicLink(file.toPath()); + isRegularFile = Files.isRegularFile(file.toPath()); + + } catch(Exception e) { } + + if(hidden || isSymbolic || (!isRegularFile && !file.isDirectory())) { + //System.out.println(name + " is hidden or a symbolic link, or just not a regular file"); + return false; + } + + return true; + + } + +} diff --git a/src/main/java/OSDetection.java b/src/main/java/OSDetection.java new file mode 100644 index 0000000..7c7a006 --- /dev/null +++ b/src/main/java/OSDetection.java @@ -0,0 +1,42 @@ +package main.java; + +/** + * Created by kristopherguzman on 2/19/16. + * + * This is a static utlity class to detect the OS. Program methods may have to adjust to the OS. + */ +public class OSDetection { + + private OSDetection() {} + + public enum OS { WINDOWS, MAC, UNIX } + public static OS OSType; + + public static void getOS() { //utility method to get OS + + String os = System.getProperty("os.name").toLowerCase(); + + if(os.contains("win")) { + + OSType = OS.WINDOWS; + System.out.println("OS: Windows"); + + } else if(os.contains("nix") || os.contains("ux") || os.contains("aix")) { + + OSType = OS.UNIX; + System.out.println("OS: Unix/Linux"); + + } else if(os.contains("mac")) { + + OSType = OS.MAC; + System.out.println("OS: Mac"); + + } else { + + System.out.println("Could not detect OS"); + + } + + } + +} diff --git a/src/main/resources/StartPage.fxml b/src/main/resources/StartPage.fxml index 17cb614..2db9ae1 100644 --- a/src/main/resources/StartPage.fxml +++ b/src/main/resources/StartPage.fxml @@ -22,7 +22,7 @@ - +