Skip to content

Commit 1eeba2f

Browse files
authored
Merge pull request nus-cs2103-AY2021S1#91 from luo-git/Branch-OpenCommand
Add OpenCommand and OpenCommandParser
2 parents bb3d81d + 30e89dc commit 1eeba2f

25 files changed

+584
-147
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package seedu.address.logic.commands;
2+
3+
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;
4+
5+
import java.awt.Desktop;
6+
import java.io.File;
7+
import java.io.IOException;
8+
9+
import javafx.collections.transformation.FilteredList;
10+
import seedu.address.logic.commands.exceptions.CommandException;
11+
import seedu.address.model.Model;
12+
import seedu.address.model.tag.Tag;
13+
import seedu.address.model.tag.TagName;
14+
15+
public class OpenCommand extends Command {
16+
17+
public static final String COMMAND_WORD = "open";
18+
19+
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Opens the file specified in the filepath of a tag. "
20+
+ "\nParameters: "
21+
+ PREFIX_TAG_NAME + "TAG_NAME "
22+
+ "\nExample: " + COMMAND_WORD + " "
23+
+ PREFIX_TAG_NAME + "cs2103 ";
24+
25+
public static final String MESSAGE_SUCCESS = "File opened! Tag: %1$s";
26+
public static final String MESSAGE_TAG_NOT_FOUND = "Tag '%s' not found!";
27+
public static final String MESSAGE_FILE_NOT_FOUND = "The file: %s doesn't exist.";
28+
29+
private final TagName tagName;
30+
31+
/**
32+
* Creates an OpenCommand to open the file specified in the {@code Tag}
33+
*/
34+
public OpenCommand(TagName tagName) {
35+
this.tagName = tagName;
36+
}
37+
38+
/**
39+
* Executes the command and opens the file specified by tagName.
40+
*
41+
* @param model {@code Model} which the command should operate on.
42+
* @throws CommandException if tagName cannot be found in model.
43+
*/
44+
@Override
45+
public CommandResult execute(Model model) throws CommandException {
46+
// Check if tagName is in tag list
47+
FilteredList<Tag> tagList =
48+
model.getAddressBook().getTagList().filtered(x -> x.getTagName().equals(tagName));
49+
if (tagList.isEmpty()) {
50+
throw new CommandException(String.format(MESSAGE_TAG_NOT_FOUND, tagName.toString()));
51+
}
52+
53+
// Get tag and prepare file to be opened
54+
Tag tagToOpen = tagList.get(0);
55+
File file = new File(tagToOpen.getFileAddress().value);
56+
57+
try {
58+
// Open file using java.awt.Desktop
59+
Desktop.getDesktop().open(file);
60+
} catch (IOException | IllegalArgumentException e) {
61+
throw new CommandException(e.getMessage(), e);
62+
}
63+
return new CommandResult(String.format(MESSAGE_SUCCESS, tagToOpen.toString()));
64+
}
65+
66+
@Override
67+
public boolean equals(Object other) {
68+
return other == this // short circuit if same object
69+
|| (other instanceof OpenCommand // instanceof handles nulls
70+
&& tagName.equals(((OpenCommand) other).tagName));
71+
}
72+
}

src/main/java/seedu/address/logic/commands/TagCommand.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package seedu.address.logic.commands;
22

33
import static java.util.Objects.requireNonNull;
4+
import static seedu.address.commons.util.AppUtil.checkArgument;
45
import static seedu.address.logic.parser.CliSyntax.PREFIX_FILE_ADDRESS;
56
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;
67

8+
import java.io.File;
9+
710
import seedu.address.logic.commands.exceptions.CommandException;
811
import seedu.address.model.Model;
12+
import seedu.address.model.tag.FileAddress;
913
import seedu.address.model.tag.Tag;
1014

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

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

2935
private final Tag toTag;
@@ -33,9 +39,17 @@ public class TagCommand extends Command {
3339
*/
3440
public TagCommand(Tag tag) {
3541
requireNonNull(tag);
42+
// Check if file is present
43+
checkArgument(filePresent(tag.getFileAddress()),
44+
String.format(MESSAGE_FILE_NOT_FOUND, tag.getFileAddress().value));
3645
toTag = tag;
3746
}
3847

48+
private boolean filePresent(FileAddress address) {
49+
File file = new File(address.value);
50+
return file.exists();
51+
}
52+
3953
/**
4054
* Executes the command and add the tag to model.
4155
*

src/main/java/seedu/address/logic/parser/AddressBookParser.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import seedu.address.logic.commands.FindCommand;
1313
import seedu.address.logic.commands.HelpCommand;
1414
import seedu.address.logic.commands.ListCommand;
15+
import seedu.address.logic.commands.OpenCommand;
1516
import seedu.address.logic.commands.ShowCommand;
1617
import seedu.address.logic.commands.TagCommand;
1718
import seedu.address.logic.commands.UntagCommand;
@@ -50,6 +51,9 @@ public Command parseCommand(String userInput) throws ParseException {
5051
case UntagCommand.COMMAND_WORD:
5152
return new UntagCommandParser().parse(arguments);
5253

54+
case OpenCommand.COMMAND_WORD:
55+
return new OpenCommandParser().parse(arguments);
56+
5357
case ClearCommand.COMMAND_WORD:
5458
return new ClearCommand();
5559

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package seedu.address.logic.parser;
2+
3+
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
4+
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;
5+
6+
import java.util.stream.Stream;
7+
8+
import seedu.address.logic.commands.OpenCommand;
9+
import seedu.address.logic.parser.exceptions.ParseException;
10+
import seedu.address.model.tag.TagName;
11+
12+
public class OpenCommandParser implements Parser<OpenCommand> {
13+
14+
/**
15+
* Parses the given {@code String} of arguments in the context of the OpenCommand
16+
* and returns an OpenCommand object for execution.
17+
* @throws ParseException if the user input does not conform the expected format
18+
*/
19+
@Override
20+
public OpenCommand parse(String args) throws ParseException {
21+
ArgumentMultimap argMultimap =
22+
ArgumentTokenizer.tokenize(args, PREFIX_TAG_NAME);
23+
24+
if (!arePrefixesPresent(argMultimap, PREFIX_TAG_NAME)
25+
|| !argMultimap.getPreamble().isEmpty()) {
26+
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, OpenCommand.MESSAGE_USAGE));
27+
}
28+
29+
TagName tagName = ParserUtil.parseTagName(argMultimap.getValue(PREFIX_TAG_NAME).get());
30+
31+
return new OpenCommand(tagName);
32+
}
33+
34+
/**
35+
* Returns true if none of the prefixes contains empty {@code Optional} values in the given
36+
* {@code ArgumentMultimap}.
37+
*/
38+
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
39+
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
40+
}
41+
}

src/main/java/seedu/address/model/tag/FileAddress.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ public class FileAddress {
1616
* The first character of the address must not be a whitespace,
1717
* otherwise " " (a blank string) becomes a valid input.
1818
*/
19-
public static final String VALIDATION_REGEX = "([A-Z|a-z]:\\\\[^*|\"<>?\\n]*)|(\\\\\\\\.*?\\\\.*)";
19+
public static final String VALIDATION_REGEX = "((((?<!\\w)[A-Z,a-z]:)|(\\.{1,2}\\\\))"
20+
+ "([^\b%\\/\\|:\\n\\\"]*))|(\"\\2([^%\\/\\|:\\n\\\"]*)\")|((?<!\\w)(\\.{1,2})?"
21+
+ "(?<!\\/)(\\/((\\\\\\b)|[^ \b%\\|:\\n\\\"\\\\\\/])+)+\\/?)";
2022

2123
public final String value;
2224

src/test/java/seedu/address/logic/LogicManagerTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import static org.junit.jupiter.api.Assertions.assertEquals;
44
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_TAG_DISPLAYED_INDEX;
55
import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
6-
import static seedu.address.logic.commands.CommandTestUtil.FILE_ADDRESS_DESC_AMY;
7-
import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
6+
import static seedu.address.logic.commands.CommandTestUtil.FILE_ADDRESS_DESC_CS2101;
7+
import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_CS2101;
88
import static seedu.address.testutil.Assert.assertThrows;
9-
import static seedu.address.testutil.TypicalTags.AMY;
9+
import static seedu.address.testutil.TypicalTags.CS2101;
1010

1111
import java.io.IOException;
1212
import java.nio.file.Path;
@@ -77,9 +77,9 @@ public void execute_storageThrowsIoException_throwsCommandException() {
7777
logic = new LogicManager(model, storage);
7878

7979
// Execute tag command
80-
String tagCommand = TagCommand.COMMAND_WORD + NAME_DESC_AMY
81-
+ FILE_ADDRESS_DESC_AMY;
82-
Tag expectedTag = new TagBuilder(AMY).build();
80+
String tagCommand = TagCommand.COMMAND_WORD + NAME_DESC_CS2101
81+
+ FILE_ADDRESS_DESC_CS2101;
82+
Tag expectedTag = new TagBuilder(CS2101).build();
8383
ModelManager expectedModel = new ModelManager();
8484
expectedModel.addTag(expectedTag);
8585
String expectedMessage = LogicManager.FILE_OPS_ERROR_MESSAGE + DUMMY_IO_EXCEPTION;

src/test/java/seedu/address/logic/commands/CommandTestUtil.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,24 @@
2323
public class CommandTestUtil {
2424

2525
// TODO All of these needs to be updated!
26+
public static final String VALID_NAME_CS2103 = "cs2103";
27+
public static final String VALID_NAME_CS2101 = "cs2101";
28+
public static final String VALID_FILE_ADDRESS_CS2103 = "./src/test/java/seedu/address/testutil/cs2103.bat";
29+
public static final String VALID_FILE_ADDRESS_CS2101 = "./src/test/java/seedu/address/testutil/cs2101.bat";
2630
public static final String VALID_NAME_AMY = "Amy Bee";
2731
public static final String VALID_NAME_BOB = "Bob Choo";
2832
public static final String VALID_FILE_ADDRESS_AMY = "c:\\a\\b\\amy.txt";
2933
public static final String VALID_FILE_ADDRESS_BOB = "c:\\a\\b\\bob.txt";
3034
public static final String VALID_TAG_HUSBAND = "husband";
3135
public static final String VALID_TAG_FRIEND = "friend";
3236

37+
public static final String NAME_DESC_CS2103 = " " + PREFIX_TAG_NAME + VALID_NAME_CS2103;
38+
public static final String NAME_DESC_CS2101 = " " + PREFIX_TAG_NAME + VALID_NAME_CS2101;
3339
public static final String NAME_DESC_AMY = " " + PREFIX_TAG_NAME + VALID_NAME_AMY;
3440
public static final String NAME_DESC_BOB = " " + PREFIX_TAG_NAME + VALID_NAME_BOB;
3541

42+
public static final String FILE_ADDRESS_DESC_CS2103 = " " + PREFIX_FILE_ADDRESS + VALID_FILE_ADDRESS_CS2103;
43+
public static final String FILE_ADDRESS_DESC_CS2101 = " " + PREFIX_FILE_ADDRESS + VALID_FILE_ADDRESS_CS2101;
3644
public static final String FILE_ADDRESS_DESC_AMY = " " + PREFIX_FILE_ADDRESS + VALID_FILE_ADDRESS_AMY;
3745
public static final String FILE_ADDRESS_DESC_BOB = " " + PREFIX_FILE_ADDRESS + VALID_FILE_ADDRESS_BOB;
3846
public static final String TAG_DESC_FRIEND = " " + VALID_TAG_FRIEND;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package seedu.address.logic.commands;
2+
3+
import java.nio.file.Path;
4+
import java.util.List;
5+
import java.util.function.Predicate;
6+
7+
import javafx.collections.ObservableList;
8+
import seedu.address.commons.core.GuiSettings;
9+
import seedu.address.model.Model;
10+
import seedu.address.model.ReadOnlyAddressBook;
11+
import seedu.address.model.ReadOnlyUserPrefs;
12+
import seedu.address.model.tag.Tag;
13+
14+
/**
15+
* A default model stub that have all of the methods failing.
16+
*/
17+
class ModelStub implements Model {
18+
@Override
19+
public void setUserPrefs(ReadOnlyUserPrefs userPrefs) {
20+
throw new AssertionError("This method should not be called.");
21+
}
22+
23+
@Override
24+
public ReadOnlyUserPrefs getUserPrefs() {
25+
throw new AssertionError("This method should not be called.");
26+
}
27+
28+
@Override
29+
public GuiSettings getGuiSettings() {
30+
throw new AssertionError("This method should not be called.");
31+
}
32+
33+
@Override
34+
public void setGuiSettings(GuiSettings guiSettings) {
35+
throw new AssertionError("This method should not be called.");
36+
}
37+
38+
@Override
39+
public Path getAddressBookFilePath() {
40+
throw new AssertionError("This method should not be called.");
41+
}
42+
43+
@Override
44+
public void setAddressBookFilePath(Path addressBookFilePath) {
45+
throw new AssertionError("This method should not be called.");
46+
}
47+
48+
@Override
49+
public void addTag(Tag tag) {
50+
throw new AssertionError("This method should not be called.");
51+
}
52+
53+
@Override
54+
public void setAddressBook(ReadOnlyAddressBook newData) {
55+
throw new AssertionError("This method should not be called.");
56+
}
57+
58+
@Override
59+
public ReadOnlyAddressBook getAddressBook() {
60+
throw new AssertionError("This method should not be called.");
61+
}
62+
63+
@Override
64+
public boolean hasTag(Tag tag) {
65+
throw new AssertionError("This method should not be called.");
66+
}
67+
68+
@Override
69+
public void deleteTag(Tag target) {
70+
throw new AssertionError("This method should not be called.");
71+
}
72+
73+
@Override
74+
public void setTag(Tag target, Tag editedTag) {
75+
throw new AssertionError("This method should not be called.");
76+
}
77+
78+
@Override
79+
public ObservableList<Tag> getFilteredTagList() {
80+
throw new AssertionError("This method should not be called.");
81+
}
82+
83+
@Override
84+
public void updateFilteredTagList(Predicate<Tag> predicate) {
85+
throw new AssertionError("This method should not be called.");
86+
}
87+
88+
@Override
89+
public List<Tag> findFilteredTagList(Predicate<Tag> predicate) {
90+
throw new AssertionError("This method should not be called.");
91+
}
92+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package seedu.address.logic.commands;
2+
3+
import static java.util.Objects.requireNonNull;
4+
5+
import java.util.ArrayList;
6+
7+
import seedu.address.model.AddressBook;
8+
import seedu.address.model.ReadOnlyAddressBook;
9+
import seedu.address.model.tag.Tag;
10+
11+
/**
12+
* A Model stub that always accept the tag being added.
13+
*/
14+
@Deprecated
15+
class ModelStubAcceptingTagAdded extends ModelStub {
16+
final ArrayList<Tag> tagsAdded = new ArrayList<>();
17+
18+
@Override
19+
public boolean hasTag(Tag tag) {
20+
requireNonNull(tag);
21+
return tagsAdded.stream().anyMatch(tag::isSameTag);
22+
}
23+
24+
@Override
25+
public void addTag(Tag tag) {
26+
requireNonNull(tag);
27+
tagsAdded.add(tag);
28+
}
29+
30+
@Override
31+
public ReadOnlyAddressBook getAddressBook() {
32+
return new AddressBook();
33+
}
34+
}

0 commit comments

Comments
 (0)