Skip to content

Commit b6727f1

Browse files
authored
Merge pull request nus-cs2103-AY2021S1#96 from li-s/branch-RenameCommand
Branch rename command
2 parents 3d0660e + 9b7838b commit b6727f1

10 files changed

Lines changed: 353 additions & 6 deletions

File tree

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
import seedu.address.model.Model;
77

88
/**
9-
* Lists all persons in the address book to the user.
9+
* Lists all tags in the address book to the user.
1010
*/
1111
public class ListCommand extends Command {
1212

1313
public static final String COMMAND_WORD = "list";
1414

15-
public static final String MESSAGE_SUCCESS = "Listed all persons";
15+
public static final String MESSAGE_SUCCESS = "Listed all tags";
1616

1717

1818
@Override
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package seedu.address.logic.commands;
2+
3+
import static java.util.Objects.requireNonNull;
4+
import static seedu.address.logic.parser.CliSyntax.PREFIX_OLD_TAG_NAME;
5+
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;
6+
7+
import java.util.List;
8+
9+
import seedu.address.logic.commands.exceptions.CommandException;
10+
import seedu.address.model.Model;
11+
import seedu.address.model.tag.FileAddress;
12+
import seedu.address.model.tag.Tag;
13+
import seedu.address.model.tag.TagName;
14+
import seedu.address.model.tag.TagNameEqualsKeywordPredicate;
15+
16+
/**
17+
* Adds a person to the address book.
18+
*/
19+
public class RetagCommand extends Command {
20+
public static final String COMMAND_WORD = "retag";
21+
22+
public static final String MESSAGE_USAGE = COMMAND_WORD
23+
+ ": Retags the tagged file identified by the old tag into the new tag.\n"
24+
+ "Parameters: "
25+
+ PREFIX_OLD_TAG_NAME + "OLD_TAG_NAME "
26+
+ PREFIX_TAG_NAME + "NEW_TAG_NAME\n"
27+
+ "Example: " + COMMAND_WORD + " "
28+
+ PREFIX_OLD_TAG_NAME + "my_files "
29+
+ PREFIX_TAG_NAME + "my_old_files ";
30+
31+
public static final String MESSAGE_RETAG_TAG_SUCCESS = "Retagged Tag: %s to Tag: %s";
32+
public static final String MESSAGE_OLD_TAG_NOT_FOUND = " %s tag not found!"
33+
+ " Please make sure that the old tag is present before retagging.";
34+
public static final String MESSAGE_DUPLICATE_TAG = "Duplicate tag name!";
35+
36+
private final TagName newTagName;
37+
private final TagName oldTagName;
38+
39+
/**
40+
* Creates a RetagCommand to retag the specified {@code oldTagName} to {@code newTagName}
41+
*/
42+
public RetagCommand(TagName oldTagName, TagName newTagName) {
43+
requireNonNull(oldTagName);
44+
requireNonNull(newTagName);
45+
46+
this.oldTagName = oldTagName;
47+
this.newTagName = newTagName;
48+
}
49+
50+
/**
51+
* Executes the command and renames the tag in the model to the new tag.
52+
*
53+
* @param model {@code Model} which the command should operate on.
54+
* @return A Command result of executing retag command.
55+
* @throws CommandException
56+
*/
57+
@Override
58+
public CommandResult execute(Model model) throws CommandException {
59+
requireNonNull(model);
60+
61+
// Check if oldTagName is in tag list
62+
List<Tag> oldTagList = model.findFilteredTagList(new TagNameEqualsKeywordPredicate(oldTagName));
63+
if (oldTagList.isEmpty()) {
64+
throw new CommandException(String.format(MESSAGE_OLD_TAG_NOT_FOUND, oldTagName.toString()));
65+
}
66+
67+
// Check if newTagName is in tag list
68+
List<Tag> newTagList = model.findFilteredTagList(new TagNameEqualsKeywordPredicate(newTagName));
69+
if (!newTagList.isEmpty()) {
70+
throw new CommandException(String.format(MESSAGE_DUPLICATE_TAG));
71+
}
72+
73+
// Get oldTagName
74+
Tag tagToChange = oldTagList.get(0);
75+
// Get file path
76+
FileAddress fileAddress = tagToChange.getFileAddress();
77+
// Delete old tag
78+
model.deleteTag(tagToChange);
79+
80+
Tag newTag = new Tag(newTagName, fileAddress);
81+
// Add new tag
82+
model.addTag(newTag);
83+
return new CommandResult(String.format(MESSAGE_RETAG_TAG_SUCCESS, oldTagName, newTagName));
84+
}
85+
86+
@Override
87+
public boolean equals(Object other) {
88+
return other == this // short circuit if same object
89+
|| (other instanceof RetagCommand // instanceof handles nulls
90+
&& newTagName.equals(((RetagCommand) other).newTagName)
91+
&& oldTagName.equals(((RetagCommand) other).oldTagName));
92+
}
93+
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@
1212
import seedu.address.model.tag.Tag;
1313

1414
/**
15-
* Adds a person to the address book.
15+
* Adds a tag to the address book.
1616
*/
1717
public class TagCommand extends Command {
1818

1919
public static final String COMMAND_WORD = "tag";
2020

21-
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a tag to the HelleFile's address book. "
21+
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a tag to the HelleFile's address book.\n"
2222
+ "Parameters: "
2323
+ PREFIX_TAG_NAME + "TAG_NAME "
24-
+ PREFIX_FILE_ADDRESS + "FILE_ADDRESS "
24+
+ PREFIX_FILE_ADDRESS + "FILE_ADDRESS\n"
2525
+ "Example: " + COMMAND_WORD + " "
2626
+ PREFIX_TAG_NAME + "cs2103 "
2727
+ PREFIX_FILE_ADDRESS + "F:\\OneDrive\\CS2013T ";

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

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

55+
case RetagCommand.COMMAND_WORD:
56+
return new RetagCommandParser().parse(arguments);
57+
5458
case OpenCommand.COMMAND_WORD:
5559
return new OpenCommandParser().parse(arguments);
5660

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

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static org.junit.jupiter.api.Assertions.assertEquals;
44
import static org.junit.jupiter.api.Assertions.assertTrue;
55
import static seedu.address.logic.parser.CliSyntax.PREFIX_FILE_ADDRESS;
6+
import static seedu.address.logic.parser.CliSyntax.PREFIX_OLD_TAG_NAME;
67
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;
78
import static seedu.address.testutil.Assert.assertThrows;
89

@@ -34,6 +35,8 @@ public class CommandTestUtil {
3435
public static final String VALID_TAG_HUSBAND = "husband";
3536
public static final String VALID_TAG_FRIEND = "friend";
3637

38+
public static final String NAME_DESC_OLD_CS2101 = " " + PREFIX_OLD_TAG_NAME + VALID_NAME_CS2101;
39+
public static final String NAME_DESC_OLD_CS2103 = " " + PREFIX_OLD_TAG_NAME + VALID_NAME_CS2103;
3740
public static final String NAME_DESC_CS2103 = " " + PREFIX_TAG_NAME + VALID_NAME_CS2103;
3841
public static final String NAME_DESC_CS2101 = " " + PREFIX_TAG_NAME + VALID_NAME_CS2101;
3942
public static final String NAME_DESC_AMY = " " + PREFIX_TAG_NAME + VALID_NAME_AMY;
@@ -46,6 +49,8 @@ public class CommandTestUtil {
4649
public static final String TAG_DESC_FRIEND = " " + VALID_TAG_FRIEND;
4750
public static final String TAG_DESC_HUSBAND = " " + VALID_TAG_HUSBAND;
4851

52+
public static final String INVALID_OLD_TAG_DESC = " " + PREFIX_OLD_TAG_NAME + "myfile&"; // '&' not allowed in names
53+
public static final String INVALID_NEW_TAG_DESC = " " + PREFIX_TAG_NAME + "myfile&"; // '&' not allowed in names
4954
public static final String INVALID_NAME_DESC = " " + PREFIX_TAG_NAME + "James&"; // '&' not allowed in names
5055
public static final String INVALID_FILE_ADDRESS_DESC = " "
5156
+ PREFIX_FILE_ADDRESS; // empty string not allowed for addresses
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package seedu.address.logic.commands;
2+
3+
import static java.util.Objects.requireNonNull;
4+
5+
import java.util.List;
6+
import java.util.function.Predicate;
7+
8+
import seedu.address.model.tag.Tag;
9+
10+
public class ModelStubWithTagAndTaglist extends ModelStub {
11+
private Tag tag;
12+
13+
ModelStubWithTagAndTaglist(Tag tag) {
14+
requireNonNull(tag);
15+
this.tag = tag;
16+
}
17+
18+
public Tag getTag() {
19+
return this.tag;
20+
}
21+
22+
@Override
23+
public void addTag(Tag tag) {
24+
this.tag = tag;
25+
}
26+
27+
@Override
28+
public void deleteTag(Tag tag) {
29+
30+
}
31+
32+
@Override
33+
public List<Tag> findFilteredTagList(Predicate<Tag> predicate) {
34+
if (predicate.test(tag)) {
35+
return List.of(tag);
36+
}
37+
38+
return List.of();
39+
}
40+
41+
@Override
42+
public boolean equals(Object other) {
43+
boolean a = other instanceof ModelStubWithTagAndTaglist;
44+
return other == this // short circuit if same object
45+
|| (other instanceof ModelStubWithTagAndTaglist // instanceof handles nulls
46+
&& ((ModelStubWithTagAndTaglist) other).tag.equals(this.tag));
47+
}
48+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package seedu.address.logic.commands;
2+
3+
import static org.junit.jupiter.api.Assertions.assertFalse;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
6+
import static seedu.address.testutil.Assert.assertThrows;
7+
8+
import org.junit.jupiter.api.BeforeEach;
9+
import org.junit.jupiter.api.Test;
10+
11+
import seedu.address.logic.commands.exceptions.CommandException;
12+
import seedu.address.model.tag.Tag;
13+
import seedu.address.model.tag.TagName;
14+
import seedu.address.testutil.TagBuilder;
15+
16+
public class RetagCommandTest {
17+
18+
private ModelStubWithTagAndTaglist modelStub;
19+
20+
@BeforeEach
21+
public void setUp() {
22+
Tag validTag = new TagBuilder().build();
23+
24+
modelStub = new ModelStubWithTagAndTaglist(validTag);
25+
}
26+
27+
@Test
28+
public void execute_duplicateNewTagName_throwsCommandException() {
29+
TagName oldTag = new TagBuilder().build().getTagName();
30+
TagName newTag = new TagBuilder().build().getTagName();
31+
32+
RetagCommand retagCommand = new RetagCommand(oldTag, newTag);
33+
34+
assertThrows(CommandException.class, RetagCommand.MESSAGE_DUPLICATE_TAG, () -> retagCommand.execute(modelStub));
35+
}
36+
37+
@Test
38+
public void execute_oldTagNotInModel_throwCommandException() {
39+
TagName oldTagName = new TagName("noExist");
40+
TagName newTagName = new TagName("noMatter");
41+
42+
RetagCommand retagCommand = new RetagCommand(oldTagName, newTagName);
43+
44+
assertThrows(CommandException.class, String.format(RetagCommand.MESSAGE_OLD_TAG_NOT_FOUND,
45+
oldTagName.tagName), () -> retagCommand.execute(modelStub));
46+
}
47+
48+
@Test
49+
public void execute_validInput_retagSuccess() {
50+
Tag newTag = new TagBuilder().withTagName("new").build();
51+
52+
TagName oldTagName = new TagBuilder().build().getTagName();
53+
TagName newTagName = newTag.getTagName();
54+
55+
RetagCommand retagCommand = new RetagCommand(oldTagName, newTagName);
56+
57+
ModelStubWithTagAndTaglist expectedModelStub = new ModelStubWithTagAndTaglist(newTag);
58+
59+
assertCommandSuccess(retagCommand, modelStub,
60+
String.format(retagCommand.MESSAGE_RETAG_TAG_SUCCESS, oldTagName, newTagName), expectedModelStub);
61+
}
62+
63+
@Test
64+
public void equals() {
65+
TagName oldTagName = new TagName("oldTag");
66+
TagName newTagName = new TagName("newTag");
67+
68+
RetagCommand retagCommand1 = new RetagCommand(oldTagName, newTagName);
69+
RetagCommand retagCommand2 = new RetagCommand(newTagName, oldTagName);
70+
71+
// same object -> returns true
72+
assertTrue(retagCommand1.equals(retagCommand1));
73+
74+
// same values -> returns true
75+
RetagCommand retagCommand1Copy = new RetagCommand(oldTagName, newTagName);
76+
assertTrue(retagCommand1.equals(retagCommand1Copy));
77+
78+
// different types -> returns false
79+
assertFalse(retagCommand1.equals(1));
80+
81+
// null -> returns false
82+
assertFalse(retagCommand1.equals(null));
83+
84+
// different tagName -> returns false
85+
assertFalse(retagCommand1.equals(retagCommand2));
86+
}
87+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public void execute_invalidTagName_throwsCommandException() {
5959
}
6060

6161
@Test
62-
public void execute_validTagName_throwsCommandException() {
62+
public void execute_validTagName_showTagFileSuccess() {
6363
Tag tagToBeShown = model.getFilteredTagList().get(INDEX_FIRST_TAG.getZeroBased());
6464
TagNameEqualsKeywordPredicate predicate = new TagNameEqualsKeywordPredicate(tagToBeShown.getTagName());
6565
ShowCommand showCommand = new ShowCommand(predicate);

0 commit comments

Comments
 (0)