Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions doc/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@ Examples:
* `find Betsy Tim John`<br>
Returns Any person having names `Betsy`, `Tim`, or `John`

## Finding all persons containing any keyword in their tag: `find-tag`
Finds persons whose tags contain any of the given keywords.<br>
Format: `find-tag KEYWORD [MORE_KEYWORDS]`

> The search is case sensitive, the order of the keywords does not matter, only the tag is searched,
and persons matching at least one keyword will be returned (i.e. `OR` search).

Examples:
* `find-tag friend`<br>
Returns `friend` but not `Friend`
* `find-tag friend CCA`<br>
Returns Any person having tags `friend` or `CCA`

## Deleting a person : `delete`
Deletes the specified person from the address book. Irreversible.<br>
Format: `delete INDEX`
Expand Down
70 changes: 70 additions & 0 deletions src/seedu/addressbook/commands/EditCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package seedu.addressbook.commands;

import java.util.HashSet;
import java.util.Set;

import seedu.addressbook.common.Messages;
import seedu.addressbook.data.exception.IllegalValueException;
import seedu.addressbook.data.person.Address;
import seedu.addressbook.data.person.Email;
import seedu.addressbook.data.person.Name;
import seedu.addressbook.data.person.Person;
import seedu.addressbook.data.person.Phone;
import seedu.addressbook.data.person.ReadOnlyPerson;
import seedu.addressbook.data.person.UniquePersonList;
import seedu.addressbook.data.person.UniquePersonList.PersonNotFoundException;
import seedu.addressbook.data.tag.Tag;
import seedu.addressbook.data.tag.UniqueTagList;

public class EditCommand extends Command {

public static final String COMMAND_WORD = "edit";

public static final String MESSAGE_USAGE = COMMAND_WORD + ":\n" + "Edit a person in the address book. "
+ "Contact details can be marked private by prepending 'p' to the prefix.\n\t"
+ "Parameters: NAME [p]p/PHONE [p]e/EMAIL [p]a/ADDRESS [t/TAG]...\n\t"
+ "Example: " + COMMAND_WORD
+ " John Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney";

public static final String MESSAGE_SUCCESS = "This person has been edited: %1$s";
public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book";

private final Person toEdit;

public EditCommand(String name,
String phone, boolean isPhonePrivate,
String email, boolean isEmailPrivate,
String address, boolean isAddressPrivate,
Set<String> tags) throws IllegalValueException {
final Set<Tag> tagSet = new HashSet<>();
for (String tagName : tags) {
tagSet.add(new Tag(tagName));
}
this.toEdit= new Person(
new Name(name),
new Phone(phone, isPhonePrivate),
new Email(email, isEmailPrivate),
new Address(address, isAddressPrivate),
new UniqueTagList(tagSet)
);
}

@Override
public CommandResult execute() {
try {
addressBook.addPerson(toEdit);
ReadOnlyPerson toRemove = null;
for (ReadOnlyPerson person : addressBook.getAllPersons()) {
if(person.getName().equals(toEdit.getName()))
toRemove = person;
}
addressBook.removePerson(toRemove);
return new CommandResult(String.format(MESSAGE_SUCCESS, toEdit));
} catch (UniquePersonList.DuplicatePersonException dpe) {
return new CommandResult(MESSAGE_DUPLICATE_PERSON);
} catch (PersonNotFoundException pnfe) {
return new CommandResult(Messages.MESSAGE_PERSON_NOT_IN_ADDRESSBOOK);
}
}

}
69 changes: 69 additions & 0 deletions src/seedu/addressbook/commands/FindTagCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package seedu.addressbook.commands;

import seedu.addressbook.data.exception.IllegalValueException;
import seedu.addressbook.data.person.ReadOnlyPerson;
import seedu.addressbook.data.tag.Tag;
import seedu.addressbook.data.tag.UniqueTagList;

import java.util.*;

/**
* Finds and lists all persons in address book whose tags contains some of the argument keywords.
* Keyword matching is case sensitive.
*/
public class FindTagCommand extends Command{

public static final String COMMAND_WORD = "find-tag";

public static final String MESSAGE_USAGE = COMMAND_WORD + ":\n" + "Finds all persons whose tags contain some of "
+ "the specified keywords (case-sensitive) and displays them as a list with index numbers.\n\t"
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n\t"
+ "Example: " + COMMAND_WORD + " friend CCA";

private final Set<String> keywords;

public FindTagCommand(Set<String> keywords) {
this.keywords = keywords;
}

/**
* Returns copy of keywords in this command.
*/
public Set<String> getKeywords() {
return new HashSet<>(keywords);
}

@Override
public CommandResult execute() {
List<ReadOnlyPerson> personsFound;
try {
personsFound = getPersonsWithTagContainingAllKeyword(keywords);
} catch (IllegalValueException e) {
return new IncorrectCommand(e.getMessage()).execute();
}
return new CommandResult(getMessageForPersonListShownSummary(personsFound), personsFound);
}

/**
* Retrieve all persons in the address book whose tags contain some of the specified keywords.
*
* @param keywords for searching
* @return list of persons found
* @throws IllegalValueException
*/
private List<ReadOnlyPerson> getPersonsWithTagContainingAllKeyword(Set<String> keywords) throws IllegalValueException {
final List<ReadOnlyPerson> matchedPersons = new ArrayList<>();
for (ReadOnlyPerson person : addressBook.getAllPersons()) {
final UniqueTagList tags = person.getTags();
for (String k : keywords) {
Tag tag = new Tag(k);
if (tags.contains(tag)) {
matchedPersons.add(person);
break;
}
}
}
return matchedPersons;
}

}
2 changes: 2 additions & 0 deletions src/seedu/addressbook/commands/HelpCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public class HelpCommand extends Command {
public static final String MESSAGE_ALL_USAGES = AddCommand.MESSAGE_USAGE
+ "\n" + DeleteCommand.MESSAGE_USAGE
+ "\n" + ClearCommand.MESSAGE_USAGE
+ "\n" + EditCommand.MESSAGE_USAGE
+ "\n" + FindCommand.MESSAGE_USAGE
+ "\n" + FindTagCommand.MESSAGE_USAGE
+ "\n" + ListCommand.MESSAGE_USAGE
+ "\n" + ViewCommand.MESSAGE_USAGE
+ "\n" + ViewAllCommand.MESSAGE_USAGE
Expand Down
48 changes: 48 additions & 0 deletions src/seedu/addressbook/commands/RemoveTag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package seedu.addressbook.commands;

import seedu.addressbook.data.exception.IllegalValueException;
import seedu.addressbook.data.person.ReadOnlyPerson;
import seedu.addressbook.data.tag.Tag;
import seedu.addressbook.data.tag.UniqueTagList;
import seedu.addressbook.data.tag.UniqueTagList.TagNotFoundException;

public class RemoveTag extends Command{
public static final String COMMAND_WORD="removetag";
public static final String MESSAGE_USAGE=COMMAND_WORD+":\n"+
"remove the tag from the address book. "+"Example: "+COMMAND_WORD+
"frends";
public static final String MESSAGE_SUCCESS="Tag deleted. ";
private final Tag toDelete;
public RemoveTag(String tagToDelete) throws IllegalValueException{
toDelete=new Tag(tagToDelete);
}
public CommandResult execute(){
removePersonWithTag();
removeTagFromList();
return new CommandResult(MESSAGE_SUCCESS);
}
private boolean removePersonWithTag(){
boolean hasDeleted=false;
for(ReadOnlyPerson person: addressBook.getAllPersons()){
final UniqueTagList tags=person.getTags();
if(tags.contains(toDelete)){
try {
tags.remove(toDelete);
} catch (TagNotFoundException e) {
e.printStackTrace();
}
hasDeleted=true;
}
}
return hasDeleted;
}
private boolean removeTagFromList(){
try {
addressBook.removeTag(toDelete);
} catch (TagNotFoundException e) {
return false;
}
return true;
}

}
72 changes: 71 additions & 1 deletion src/seedu/addressbook/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ public Parser() {}
*
* @param userInput full user input string
* @return the command based on the user input
* @throws IllegalValueException
*/
public Command parseCommand(String userInput) {
public Command parseCommand(String userInput) {
final Matcher matcher = BASIC_COMMAND_FORMAT.matcher(userInput.trim());
if (!matcher.matches()) {
return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE));
Expand All @@ -68,8 +69,14 @@ public Command parseCommand(String userInput) {
case ClearCommand.COMMAND_WORD:
return new ClearCommand();

case EditCommand.COMMAND_WORD:
return prepareEdit(arguments);

case FindCommand.COMMAND_WORD:
return prepareFind(arguments);

case FindTagCommand.COMMAND_WORD:
return prepareFindTag(arguments);

case ListCommand.COMMAND_WORD:
return new ListCommand();
Expand All @@ -79,6 +86,9 @@ public Command parseCommand(String userInput) {

case ViewAllCommand.COMMAND_WORD:
return prepareViewAll(arguments);

case RemoveTag.COMMAND_WORD:
return prepareDeleteTag(arguments);

case ExitCommand.COMMAND_WORD:
return new ExitCommand();
Expand All @@ -88,6 +98,16 @@ public Command parseCommand(String userInput) {
return new HelpCommand();
}
}
private Command prepareDeleteTag(String args){
Command deleteTag;
try {
deleteTag=new RemoveTag(args);
return deleteTag;
} catch (IllegalValueException e) {
return new IncorrectCommand(e.getMessage());
}

}

/**
* Parses arguments in the context of the add person command.
Expand Down Expand Up @@ -227,6 +247,56 @@ private Command prepareFind(String args) {
final Set<String> keywordSet = new HashSet<>(Arrays.asList(keywords));
return new FindCommand(keywordSet);
}

/**
* Parses arguments in the context of the find tag command.
*
* @param args full command args string
* @return the prepared command
*/
private Command prepareFindTag(String args) {
final Matcher matcher = KEYWORDS_ARGS_FORMAT.matcher(args.trim());
if (!matcher.matches()) {
return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT,
FindCommand.MESSAGE_USAGE));
}

// keywords delimited by whitespace
final String[] keywords = matcher.group("keywords").split("\\s+");
final Set<String> keywordSet = new HashSet<>(Arrays.asList(keywords));
return new FindTagCommand(keywordSet);
}


/**
* Parses arguments in the context of the add person command.
*
* @param args full command args string
* @return the prepared command
*/
private Command prepareEdit(String args){
final Matcher matcher = PERSON_DATA_ARGS_FORMAT.matcher(args.trim());
// Validate arg string format
if (!matcher.matches()) {
return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE));
}
try {
return new EditCommand(
matcher.group("name"),

matcher.group("phone"),
isPrivatePrefixPresent(matcher.group("isPhonePrivate")),

matcher.group("email"),
isPrivatePrefixPresent(matcher.group("isEmailPrivate")),

matcher.group("address"),
isPrivatePrefixPresent(matcher.group("isAddressPrivate")),

getTagsFromArgs(matcher.group("tagArguments"))
);
} catch (IllegalValueException ive) {
return new IncorrectCommand(ive.getMessage());
}
}
}
1 change: 1 addition & 0 deletions test/java/seedu/addressbook/parser/ParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ private void parseAndAssertIncorrectWithMessage(String feedbackMessage, String..
* @param input to be parsed
* @param expectedCommandClass expected class of returned command
* @return the parsed command object
*
*/
private <T extends Command> T parseAndAssertCommandType(String input, Class<T> expectedCommandClass) {
final Command result = parser.parseCommand(input);
Expand Down