Skip to content

Commit

Permalink
Merge pull request nus-cs2103-AY2021S1#91 from luo-git/Branch-OpenCom…
Browse files Browse the repository at this point in the history
…mand

Add OpenCommand and OpenCommandParser
  • Loading branch information
li-s authored Oct 13, 2020
2 parents bb3d81d + 30e89dc commit 1eeba2f
Show file tree
Hide file tree
Showing 25 changed files with 584 additions and 147 deletions.
72 changes: 72 additions & 0 deletions src/main/java/seedu/address/logic/commands/OpenCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package seedu.address.logic.commands;

import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;

import javafx.collections.transformation.FilteredList;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.tag.Tag;
import seedu.address.model.tag.TagName;

public class OpenCommand extends Command {

public static final String COMMAND_WORD = "open";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Opens the file specified in the filepath of a tag. "
+ "\nParameters: "
+ PREFIX_TAG_NAME + "TAG_NAME "
+ "\nExample: " + COMMAND_WORD + " "
+ PREFIX_TAG_NAME + "cs2103 ";

public static final String MESSAGE_SUCCESS = "File opened! Tag: %1$s";
public static final String MESSAGE_TAG_NOT_FOUND = "Tag '%s' not found!";
public static final String MESSAGE_FILE_NOT_FOUND = "The file: %s doesn't exist.";

private final TagName tagName;

/**
* Creates an OpenCommand to open the file specified in the {@code Tag}
*/
public OpenCommand(TagName tagName) {
this.tagName = tagName;
}

/**
* Executes the command and opens the file specified by tagName.
*
* @param model {@code Model} which the command should operate on.
* @throws CommandException if tagName cannot be found in model.
*/
@Override
public CommandResult execute(Model model) throws CommandException {
// Check if tagName is in tag list
FilteredList<Tag> tagList =
model.getAddressBook().getTagList().filtered(x -> x.getTagName().equals(tagName));
if (tagList.isEmpty()) {
throw new CommandException(String.format(MESSAGE_TAG_NOT_FOUND, tagName.toString()));
}

// Get tag and prepare file to be opened
Tag tagToOpen = tagList.get(0);
File file = new File(tagToOpen.getFileAddress().value);

try {
// Open file using java.awt.Desktop
Desktop.getDesktop().open(file);
} catch (IOException | IllegalArgumentException e) {
throw new CommandException(e.getMessage(), e);
}
return new CommandResult(String.format(MESSAGE_SUCCESS, tagToOpen.toString()));
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof OpenCommand // instanceof handles nulls
&& tagName.equals(((OpenCommand) other).tagName));
}
}
14 changes: 14 additions & 0 deletions src/main/java/seedu/address/logic/commands/TagCommand.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.AppUtil.checkArgument;
import static seedu.address.logic.parser.CliSyntax.PREFIX_FILE_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;

import java.io.File;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.tag.FileAddress;
import seedu.address.model.tag.Tag;

/**
Expand All @@ -24,6 +28,8 @@ public class TagCommand extends Command {
+ PREFIX_FILE_ADDRESS + "F:\\OneDrive\\CS2013T ";

public static final String MESSAGE_SUCCESS = "New tag added: %1$s";
public static final String MESSAGE_FILE_NOT_FOUND = "File not found at %s!"
+ "Please make sure that file is present before adding.";
public static final String MESSAGE_DUPLICATE_TAG = "Duplicate tag name!";

private final Tag toTag;
Expand All @@ -33,9 +39,17 @@ public class TagCommand extends Command {
*/
public TagCommand(Tag tag) {
requireNonNull(tag);
// Check if file is present
checkArgument(filePresent(tag.getFileAddress()),
String.format(MESSAGE_FILE_NOT_FOUND, tag.getFileAddress().value));
toTag = tag;
}

private boolean filePresent(FileAddress address) {
File file = new File(address.value);
return file.exists();
}

/**
* Executes the command and add the tag to model.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.OpenCommand;
import seedu.address.logic.commands.ShowCommand;
import seedu.address.logic.commands.TagCommand;
import seedu.address.logic.commands.UntagCommand;
Expand Down Expand Up @@ -50,6 +51,9 @@ public Command parseCommand(String userInput) throws ParseException {
case UntagCommand.COMMAND_WORD:
return new UntagCommandParser().parse(arguments);

case OpenCommand.COMMAND_WORD:
return new OpenCommandParser().parse(arguments);

case ClearCommand.COMMAND_WORD:
return new ClearCommand();

Expand Down
41 changes: 41 additions & 0 deletions src/main/java/seedu/address/logic/parser/OpenCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package seedu.address.logic.parser;

import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;

import java.util.stream.Stream;

import seedu.address.logic.commands.OpenCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.tag.TagName;

public class OpenCommandParser implements Parser<OpenCommand> {

/**
* Parses the given {@code String} of arguments in the context of the OpenCommand
* and returns an OpenCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
@Override
public OpenCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_TAG_NAME);

if (!arePrefixesPresent(argMultimap, PREFIX_TAG_NAME)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, OpenCommand.MESSAGE_USAGE));
}

TagName tagName = ParserUtil.parseTagName(argMultimap.getValue(PREFIX_TAG_NAME).get());

return new OpenCommand(tagName);
}

/**
* Returns true if none of the prefixes contains empty {@code Optional} values in the given
* {@code ArgumentMultimap}.
*/
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
}
4 changes: 3 additions & 1 deletion src/main/java/seedu/address/model/tag/FileAddress.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ public class FileAddress {
* The first character of the address must not be a whitespace,
* otherwise " " (a blank string) becomes a valid input.
*/
public static final String VALIDATION_REGEX = "([A-Z|a-z]:\\\\[^*|\"<>?\\n]*)|(\\\\\\\\.*?\\\\.*)";
public static final String VALIDATION_REGEX = "((((?<!\\w)[A-Z,a-z]:)|(\\.{1,2}\\\\))"
+ "([^\b%\\/\\|:\\n\\\"]*))|(\"\\2([^%\\/\\|:\\n\\\"]*)\")|((?<!\\w)(\\.{1,2})?"
+ "(?<!\\/)(\\/((\\\\\\b)|[^ \b%\\|:\\n\\\"\\\\\\/])+)+\\/?)";

public final String value;

Expand Down
12 changes: 6 additions & 6 deletions src/test/java/seedu/address/logic/LogicManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_TAG_DISPLAYED_INDEX;
import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
import static seedu.address.logic.commands.CommandTestUtil.FILE_ADDRESS_DESC_AMY;
import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
import static seedu.address.logic.commands.CommandTestUtil.FILE_ADDRESS_DESC_CS2101;
import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_CS2101;
import static seedu.address.testutil.Assert.assertThrows;
import static seedu.address.testutil.TypicalTags.AMY;
import static seedu.address.testutil.TypicalTags.CS2101;

import java.io.IOException;
import java.nio.file.Path;
Expand Down Expand Up @@ -77,9 +77,9 @@ public void execute_storageThrowsIoException_throwsCommandException() {
logic = new LogicManager(model, storage);

// Execute tag command
String tagCommand = TagCommand.COMMAND_WORD + NAME_DESC_AMY
+ FILE_ADDRESS_DESC_AMY;
Tag expectedTag = new TagBuilder(AMY).build();
String tagCommand = TagCommand.COMMAND_WORD + NAME_DESC_CS2101
+ FILE_ADDRESS_DESC_CS2101;
Tag expectedTag = new TagBuilder(CS2101).build();
ModelManager expectedModel = new ModelManager();
expectedModel.addTag(expectedTag);
String expectedMessage = LogicManager.FILE_OPS_ERROR_MESSAGE + DUMMY_IO_EXCEPTION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,24 @@
public class CommandTestUtil {

// TODO All of these needs to be updated!
public static final String VALID_NAME_CS2103 = "cs2103";
public static final String VALID_NAME_CS2101 = "cs2101";
public static final String VALID_FILE_ADDRESS_CS2103 = "./src/test/java/seedu/address/testutil/cs2103.bat";
public static final String VALID_FILE_ADDRESS_CS2101 = "./src/test/java/seedu/address/testutil/cs2101.bat";
public static final String VALID_NAME_AMY = "Amy Bee";
public static final String VALID_NAME_BOB = "Bob Choo";
public static final String VALID_FILE_ADDRESS_AMY = "c:\\a\\b\\amy.txt";
public static final String VALID_FILE_ADDRESS_BOB = "c:\\a\\b\\bob.txt";
public static final String VALID_TAG_HUSBAND = "husband";
public static final String VALID_TAG_FRIEND = "friend";

public static final String NAME_DESC_CS2103 = " " + PREFIX_TAG_NAME + VALID_NAME_CS2103;
public static final String NAME_DESC_CS2101 = " " + PREFIX_TAG_NAME + VALID_NAME_CS2101;
public static final String NAME_DESC_AMY = " " + PREFIX_TAG_NAME + VALID_NAME_AMY;
public static final String NAME_DESC_BOB = " " + PREFIX_TAG_NAME + VALID_NAME_BOB;

public static final String FILE_ADDRESS_DESC_CS2103 = " " + PREFIX_FILE_ADDRESS + VALID_FILE_ADDRESS_CS2103;
public static final String FILE_ADDRESS_DESC_CS2101 = " " + PREFIX_FILE_ADDRESS + VALID_FILE_ADDRESS_CS2101;
public static final String FILE_ADDRESS_DESC_AMY = " " + PREFIX_FILE_ADDRESS + VALID_FILE_ADDRESS_AMY;
public static final String FILE_ADDRESS_DESC_BOB = " " + PREFIX_FILE_ADDRESS + VALID_FILE_ADDRESS_BOB;
public static final String TAG_DESC_FRIEND = " " + VALID_TAG_FRIEND;
Expand Down
92 changes: 92 additions & 0 deletions src/test/java/seedu/address/logic/commands/ModelStub.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package seedu.address.logic.commands;

import java.nio.file.Path;
import java.util.List;
import java.util.function.Predicate;

import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.Model;
import seedu.address.model.ReadOnlyAddressBook;
import seedu.address.model.ReadOnlyUserPrefs;
import seedu.address.model.tag.Tag;

/**
* A default model stub that have all of the methods failing.
*/
class ModelStub implements Model {
@Override
public void setUserPrefs(ReadOnlyUserPrefs userPrefs) {
throw new AssertionError("This method should not be called.");
}

@Override
public ReadOnlyUserPrefs getUserPrefs() {
throw new AssertionError("This method should not be called.");
}

@Override
public GuiSettings getGuiSettings() {
throw new AssertionError("This method should not be called.");
}

@Override
public void setGuiSettings(GuiSettings guiSettings) {
throw new AssertionError("This method should not be called.");
}

@Override
public Path getAddressBookFilePath() {
throw new AssertionError("This method should not be called.");
}

@Override
public void setAddressBookFilePath(Path addressBookFilePath) {
throw new AssertionError("This method should not be called.");
}

@Override
public void addTag(Tag tag) {
throw new AssertionError("This method should not be called.");
}

@Override
public void setAddressBook(ReadOnlyAddressBook newData) {
throw new AssertionError("This method should not be called.");
}

@Override
public ReadOnlyAddressBook getAddressBook() {
throw new AssertionError("This method should not be called.");
}

@Override
public boolean hasTag(Tag tag) {
throw new AssertionError("This method should not be called.");
}

@Override
public void deleteTag(Tag target) {
throw new AssertionError("This method should not be called.");
}

@Override
public void setTag(Tag target, Tag editedTag) {
throw new AssertionError("This method should not be called.");
}

@Override
public ObservableList<Tag> getFilteredTagList() {
throw new AssertionError("This method should not be called.");
}

@Override
public void updateFilteredTagList(Predicate<Tag> predicate) {
throw new AssertionError("This method should not be called.");
}

@Override
public List<Tag> findFilteredTagList(Predicate<Tag> predicate) {
throw new AssertionError("This method should not be called.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import java.util.ArrayList;

import seedu.address.model.AddressBook;
import seedu.address.model.ReadOnlyAddressBook;
import seedu.address.model.tag.Tag;

/**
* A Model stub that always accept the tag being added.
*/
@Deprecated
class ModelStubAcceptingTagAdded extends ModelStub {
final ArrayList<Tag> tagsAdded = new ArrayList<>();

@Override
public boolean hasTag(Tag tag) {
requireNonNull(tag);
return tagsAdded.stream().anyMatch(tag::isSameTag);
}

@Override
public void addTag(Tag tag) {
requireNonNull(tag);
tagsAdded.add(tag);
}

@Override
public ReadOnlyAddressBook getAddressBook() {
return new AddressBook();
}
}
Loading

0 comments on commit 1eeba2f

Please sign in to comment.