// TODO: Make ln fit the 30 line public void ln(String firstPath, String secondPath) throws Exception { // Initialize the variables. JShellItem targetItem; JShellItem aliasItem; String newName; Directory destinationDirectory; // Find and reference the target item. Throw Exception if the path // doesn't exist. targetItem = getItemAtPath(firstPath, 0); if (targetItem == null) { throw new Exception(firstPath + ": doesn't exist."); } // Find and reference the destination Directory. if (secondPath.endsWith("/")) { destinationDirectory = (Directory) getItemAtPath(secondPath, 0); newName = targetItem.getName(); } else { destinationDirectory = (Directory) getItemAtPath(secondPath, 1); newName = secondPath.substring(secondPath.lastIndexOf("/") + 1); } // If the Directory destination is not found. if (destinationDirectory == null) { throw new Exception(secondPath + " is an invalid destination path."); } // Throw Exception when there is a JShellItem that already exist within // the destination Directory. if (destinationDirectory.contains(newName)) { throw new Exception(secondPath + ": already exists."); } // If the target item is a Directory object. if (targetItem instanceof Directory) // Create a new Directory object that will references it's contents // from the target item. aliasItem = new DirectoryAlias( newName, destinationDirectory.getPath() + newName + "/", destinationDirectory, (Directory) targetItem); // If the target item is a File object. else // Create a new FileAlias object that will reference it's contents // from the target item. aliasItem = new FileAlias( newName, destinationDirectory.getPath() + newName, destinationDirectory, (File) targetItem); // Add the alias object to the destination Directory. destinationDirectory.addItem(aliasItem); }
/** * Print the path of the files specified by the paths argument whose path contains regex. * * @param regex is a String regular expression * @param paths is a List of paths */ public String find(String regex, List<String> paths) throws Exception { String results = ""; regex = regex.replace("?", ".?").replace("*", ".*?"); Pattern regexPattern = Pattern.compile(regex); Matcher regexMatcher; // If the user input was empty, call find on the current directory. if (paths.isEmpty()) { paths.add(currentDirectory_.getPath()); } // Loop through the paths. for (String path : paths) { List<String> recursiveListing = recurseOnPath(path, true); // Loop through the list of JShellItems found recursively. for (String name : recursiveListing) { regexMatcher = regexPattern.matcher(name); // Append to results if match is found. if (regexMatcher.find()) { results = results + name + "\n"; } } } if (results.endsWith("\n")) { results = results.substring(0, results.length() - 1); } else { results = "find: no such file or directory."; } // Return the completed output. return results; }
/** * Copy file or directory oldFile to newFile; * * @param oldFile a full path to a JShellItem or the name of a JShellItem in the current directory * which needs to be copied. * @param newFile a full path to a directory or the name of a directory in the current directory * to which oldFile needs to be copied. */ public void cp(String oldPath, String newPath) throws Exception { Directory destinationParent; String newName; if (oldPath.equals(newPath)) { return; } JShellItem oldItem = getItemAtPath(oldPath, 0); if (oldItem == null) { throw new Exception(oldItem + " does not exist."); } if (newPath.endsWith("/")) { destinationParent = (Directory) getItemAtPath(newPath, 0); newName = oldItem.getName(); } else { destinationParent = (Directory) getItemAtPath(newPath, 1); newName = newPath.substring(newPath.lastIndexOf("/") + 1); } if (destinationParent == null) { throw new Exception(newPath + " is an invalid destination path."); } if (destinationParent.contains(newName)) { throw new Exception(destinationParent.getPath() + newName + " already exists."); } if (oldItem instanceof File) { File newItem = new File( newName, destinationParent.getPath() + "/" + newName, destinationParent, ((File) oldItem).getContent()); destinationParent.addItem(newItem); } else { if (destinationParent.isChildOf((Directory) oldItem)) { throw new Exception( String.format("cp: cannot copy '%s' into itself, '%s'", oldPath, newPath)); } Directory newItem = new Directory(newName, destinationParent.getPath() + newName + "/", destinationParent); destinationParent.addItem(newItem); for (JShellItem item : ((Directory) oldItem).getContents().values()) { cp(item.getPath(), newItem.getPath()); } } }
/** * Creates Directories in the paths provided. The path is considered to be invalid if (1) There is * already an item with the same path. (2) The immediate parent of the specified path does not * exist. * * @throws Exception if a provided path is invalid. * @param paths is the list of paths. Paths can be relative to the current directory or the full * path. */ public void mkdir(List<String> paths) throws Exception { for (String dir : paths) { if (!dir.startsWith("/")) { dir = currentDirectory_.getPath().concat(dir); } while (dir.endsWith("/")) { dir = dir.substring(0, dir.length() - 1); } String[] dirs = dir.split("/"); String dirName = dirs[dirs.length - 1]; dir = dir.substring(0, dir.length() - dirName.length()); Directory parent = (Directory) getItemAtPath(dir, 0); if (parent == null) { throw new NullPointerException("The path specified is " + "incorrect."); } if (parent.getContents().keySet().contains(dirName)) { throw new Exception("A directory already exists at that " + "path."); } parent.addItem(new Directory(dirName, parent.getPath() + dirName + "/", parent)); } }
/** * Return the names of the contained items, if path leads to a Directory. Or, return the path * provided, if it leads to a File. * * @param paths a list of Strings containing the desired paths. * @return a String containing the relevant contents. */ public String ls(List<String> paths) throws Exception { // If ls is called without parameters. if (paths.isEmpty()) { if (!currentOptions_.equals("R")) { if (currentDirectory_.getSize() == 0) { return ""; } else { return currentDirectory_.ls().substring(2); } } paths.add(currentDirectory_.getPath()); return ls(paths); // If ls is called with paramters. } else { String lsOutput = ""; for (int i = 0; i < paths.size(); i++) { JShellItem target = getItemAtPath(paths.get(i), 0); if (!lsOutput.isEmpty()) { lsOutput += "\n"; } lsOutput += paths.get(i); if (target == null) { lsOutput += ": No such file or directory"; } else { if (target instanceof Directory && currentOptions_.equals("R") && ((Directory) target).getNumDirectories() > 0 && !(target instanceof DirectoryAlias)) { List<String> recursivePath = recurseOnPath(paths.get(i), false); Collections.reverse(recursivePath); lsOutput += target.ls(); lsOutput += "\n"; lsOutput += ls(recursivePath.subList(1, recursivePath.size())); } else { // list paths separately lsOutput += target.ls(); // if there are more paths, print a blank line if (i < paths.size() - 1) { lsOutput += "\n"; } // notify user if there is an error in the path // specified } } } return lsOutput; } }
/** * Creates a file at the path passed in the parameter. * * @param path The path at which the file is to be created. The path has to contain the file name * as well. */ public void mkfile(String path) throws Exception { Directory target = currentDirectory_; if (path.startsWith("/")) { String targetPath = path.substring(0, path.lastIndexOf("/")); target = (Directory) getItemAtPath(targetPath, 0); } if (target != null) { String fileName = path.substring(path.lastIndexOf("/") + 1); if (path.indexOf("/") != -1) { target = (Directory) getItemAtPath(path.substring(0, path.lastIndexOf("/")), 0); } target.addItem(new File(fileName, target.getPath() + fileName, target)); } }
/** * Changes current working directory to dir. * * @param dir name of a directory in the current directory or may be a full path; '..' means a * parent directory and '.' means the current directory; The directory separator must be '/', * the forward slash. */ public void cd(String dir) throws Exception { // Initialize the destination directory. JShellItem destination; String path = dir; // If user's input path doesn't begin with "/", use relative path // with the current directory. if (!dir.startsWith("/")) { dir = currentDirectory_.getPath().concat(dir); } // If user's input path doesn't end with "/", concatenate it to // complete a full path. if (!dir.endsWith("/")) { dir = dir.concat("/"); } // Find the directory location. destination = getItemAtPath(dir, 0); // Check to see if user is trying to change directory into a File // object. if (destination instanceof File) { System.out.println(path + ": Not a directory."); // destination is a Directory Object. } else { // Use try to catch NullPointerException for directories that // doesn't exist. // If path exists, location of the directory is found. if (destination != null) { currentDirectory_ = (Directory) destination; } else { // The directory doesn't exist. throw new NullPointerException(path + ": no such directory."); } } }
/** * Move file or directory oldFile to newFile; * * @param oldFile a full path to a JShellItem or the name of a JShellItem in the current directory * which needs to be moved. * @param newFile a full path to a directory or the name of a directory in the current directory * to which oldFile needs to be moved. */ public void mv(String oldFile, String newFile) throws Exception { JShellItem source = getItemAtPath(oldFile, 0); if (source == null) { throw new Exception(oldFile + ": doesn't exist."); } Directory sourceParent = source.getParentDirectory(); Directory destinationParent; String newName; if (newFile.endsWith("/")) { destinationParent = (Directory) getItemAtPath(newFile, 0); newName = source.getName(); } else { destinationParent = (Directory) getItemAtPath(newFile, 1); newName = newFile.substring(newFile.lastIndexOf("/") + 1); } if (destinationParent == null) { throw new Exception(newFile + ": invalid destination path."); } if (destinationParent.contains(newName)) { throw new Exception(newFile + ": already exists."); } sourceParent.removeItem(source); source.setName(newName); if (source instanceof Directory) { if (destinationParent.isChildOf((Directory) source)) { throw new Exception( String.format( "mv: cannot move '%s' to a subdirectory of itself, '%s'", oldFile, newFile)); } newName.concat("/"); } source.setPath(destinationParent.getPath() + newName); source.setParentDirectory(destinationParent); destinationParent.addItem(source); }
/** Prints the prompt in the path + # format. */ public void printPrompt() { System.out.print(currentDirectory_.getPath() + "# "); }
/** * Return the current working directory as a full path. * * @return the String representation of current working directory's full path. */ public String pwd() { // Return the current working directory. return currentDirectory_.getPath(); }