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 @@ - +