Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
dasha3412 committed Oct 10, 2024
2 parents 87125c2 + 1a54902 commit 3a8b0ed
Show file tree
Hide file tree
Showing 20 changed files with 385 additions and 68 deletions.
58 changes: 58 additions & 0 deletions src/main/java/seedu/address/logic/commands/FilterCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.person.TagContainsKeywordsPredicate;

/**
* Finds and lists all persons in address book whose tag contains any of the argument keywords.
* Keyword matching is case-insensitive.
*/
public class FilterCommand extends Command {

public static final String COMMAND_WORD = "filter";

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

private final TagContainsKeywordsPredicate predicate;

public FilterCommand(TagContainsKeywordsPredicate predicate) {
this.predicate = predicate;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
model.updateFilteredPersonListByTag(predicate);
return new CommandResult(
String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof FilterCommand otherFindCommand)) {
return false;
}

return predicate.equals(otherFindCommand.predicate);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("predicate", predicate)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ public AddCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);

if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL)
if (!arePrefixesPresent(argMultimap, PREFIX_NAME)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
}

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS);
Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get());
Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get());
Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get());
Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).orElse(""));
Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).orElse(""));
Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).orElse(""));
Set<Tag> tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG));

Person person = new Person(name, phone, email, address, tagList);
Expand Down
40 changes: 13 additions & 27 deletions src/main/java/seedu/address/logic/parser/AddressBookParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import seedu.address.logic.commands.DeleteCommand;
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FilterCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
Expand Down Expand Up @@ -51,36 +52,21 @@ public Command parseCommand(String userInput) throws ParseException {
// Lower level log messages are used sparingly to minimize noise in the code.
logger.fine("Command word: " + commandWord + "; Arguments: " + arguments);

switch (commandWord) {

case AddCommand.COMMAND_WORD:
return new AddCommandParser().parse(arguments);

case EditCommand.COMMAND_WORD:
return new EditCommandParser().parse(arguments);

case DeleteCommand.COMMAND_WORD:
return new DeleteCommandParser().parse(arguments);

case ClearCommand.COMMAND_WORD:
return new ClearCommand();

case FindCommand.COMMAND_WORD:
return new FindCommandParser().parse(arguments);

case ListCommand.COMMAND_WORD:
return new ListCommand();

case ExitCommand.COMMAND_WORD:
return new ExitCommand();

case HelpCommand.COMMAND_WORD:
return new HelpCommand();

default:
return switch (commandWord) {
case AddCommand.COMMAND_WORD -> new AddCommandParser().parse(arguments);
case EditCommand.COMMAND_WORD -> new EditCommandParser().parse(arguments);
case DeleteCommand.COMMAND_WORD -> new DeleteCommandParser().parse(arguments);
case ClearCommand.COMMAND_WORD -> new ClearCommand();
case FindCommand.COMMAND_WORD -> new FindCommandParser().parse(arguments);
case FilterCommand.COMMAND_WORD -> new FilterCommandParser().parse(arguments);
case ListCommand.COMMAND_WORD -> new ListCommand();
case ExitCommand.COMMAND_WORD -> new ExitCommand();
case HelpCommand.COMMAND_WORD -> new HelpCommand();
default -> {
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
}
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public EditCommand parse(String args) throws ParseException {
editPersonDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()));
}
if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) {
editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()));
editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).orElse("")));
}
if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) {
editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).orElse("")));
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/seedu/address/logic/parser/FilterCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import java.util.Arrays;

import seedu.address.logic.commands.FilterCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.TagContainsKeywordsPredicate;


/**
* Parses input arguments and creates a new FindCommand object
*/
public class FilterCommandParser implements Parser<FilterCommand> {

/**
* Parses the given {@code String} of arguments in the context of the FilterCommand
* and returns a FilterCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public FilterCommand parse(String args) throws ParseException {
String trimmedArgs = args.trim();
if (trimmedArgs.isEmpty()) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterCommand.MESSAGE_USAGE));
}

String[] nameKeywords = trimmedArgs.split("\\s+");

return new FilterCommand(new TagContainsKeywordsPredicate(Arrays.asList(nameKeywords)));
}

}
11 changes: 9 additions & 2 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.person.Person;
import seedu.address.model.tag.Tag;

/**
* The API of the Model component.
Expand Down Expand Up @@ -80,8 +81,14 @@ public interface Model {
ObservableList<Person> getFilteredPersonList();

/**
* Updates the filter of the filtered person list to filter by the given {@code predicate}.
* Updates the filter of the filtered person list to filter by the given {@code personPredicate}.
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredPersonList(Predicate<Person> predicate);
void updateFilteredPersonList(Predicate<Person> personPredicate);

/**
* Updates the filter of the filtered person list to filter by the given {@code tagPredicate}.
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredPersonListByTag(Predicate<Tag> tagPredicate);
}
10 changes: 8 additions & 2 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
import seedu.address.model.person.Person;
import seedu.address.model.tag.Tag;

/**
* Represents the in-memory model of the address book data.
Expand Down Expand Up @@ -128,18 +129,23 @@ public void updateFilteredPersonList(Predicate<Person> predicate) {
filteredPersons.setPredicate(predicate);
}

@Override
public void updateFilteredPersonListByTag(Predicate<Tag> predicate) {
requireNonNull(predicate);
filteredPersons.setPredicate(person -> person.getTags().stream().anyMatch(predicate));
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof ModelManager)) {
if (!(other instanceof ModelManager otherModelManager)) {
return false;
}

ModelManager otherModelManager = (ModelManager) other;
return addressBook.equals(otherModelManager.addressBook)
&& userPrefs.equals(otherModelManager.userPrefs)
&& filteredPersons.equals(otherModelManager.filteredPersons);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/model/person/Email.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class Email {
+ "(-" + ALPHANUMERIC_NO_UNDERSCORE + ")*";
private static final String DOMAIN_LAST_PART_REGEX = "(" + DOMAIN_PART_REGEX + "){2,}$"; // At least two chars
private static final String DOMAIN_REGEX = "(" + DOMAIN_PART_REGEX + "\\.)*" + DOMAIN_LAST_PART_REGEX;
public static final String VALIDATION_REGEX = LOCAL_PART_REGEX + "@" + DOMAIN_REGEX;
public static final String VALIDATION_REGEX = "(" + LOCAL_PART_REGEX + "@" + DOMAIN_REGEX + ")?\\s*";

public final String value;

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/seedu/address/model/person/Phone.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public class Phone {

public static final String MESSAGE_CONSTRAINTS =
"Phone numbers should only contain numbers, and it should be at least 3 digits long";
public static final String VALIDATION_REGEX = "\\d{3,}";

// allow either a blank string, whitespaces (will be trimmed) or require all numbers and at least 3 digits long
public static final String VALIDATION_REGEX = "(\\d{3,})?\\s*";
public final String value;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package seedu.address.model.person;

import java.util.List;
import java.util.function.Predicate;

import seedu.address.commons.util.StringUtil;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.model.tag.Tag;

/**
* Tests that a {@code Person}'s {@code Tag } matches any of the keywords given.
*/
public class TagContainsKeywordsPredicate implements Predicate<Tag> {
private final List<String> keywords;

public TagContainsKeywordsPredicate(List<String> keywords) {
this.keywords = keywords;
}

@Override
public boolean test(Tag tag) {
return keywords.stream()
.anyMatch(keyword -> StringUtil.containsWordIgnoreCase(tag.tagName, keyword));
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof TagContainsKeywordsPredicate otherNameContainsKeywordsPredicate)) {
return false;
}

return keywords.equals(otherNameContainsKeywordsPredicate.keywords);
}

@Override
public String toString() {
return new ToStringBuilder(this).add("keywords", keywords).toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import seedu.address.model.ReadOnlyAddressBook;
import seedu.address.model.ReadOnlyUserPrefs;
import seedu.address.model.person.Person;
import seedu.address.model.tag.Tag;
import seedu.address.testutil.PersonBuilder;

public class AddCommandTest {
Expand Down Expand Up @@ -157,6 +158,11 @@ public ObservableList<Person> getFilteredPersonList() {
public void updateFilteredPersonList(Predicate<Person> predicate) {
throw new AssertionError("This method should not be called.");
}

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

/**
Expand Down
19 changes: 18 additions & 1 deletion src/test/java/seedu/address/logic/commands/CommandTestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,54 @@ public class CommandTestUtil {
public static final String VALID_NAME_AMY = "Amy Bee";
public static final String VALID_NAME_BOB = "Bob Choo";
public static final String VALID_NAME_CLIVE = "Clive Fairfield";
public static final String VALID_NAME_DOMINIC = "Dominic Cheung";
public static final String VALID_NAME_ERIC = "Eric Caroll";
public static final String VALID_PHONE_AMY = "11111111";
public static final String VALID_PHONE_BOB = "22222222";
public static final String VALID_PHONE_CLIVE = "33333333";
public static final String VALID_PHONE_DOMINIC = "";
public static final String VALID_PHONE_ERIC = "65555656";
public static final String VALID_EMAIL_AMY = "[email protected]";
public static final String VALID_EMAIL_BOB = "[email protected]";
public static final String VALID_EMAIL_CLIVE = "[email protected]";
public static final String VALID_EMAIL_DOMINIC = "[email protected]";
public static final String VALID_EMAIL_ERIC = "";
public static final String VALID_ADDRESS_AMY = "Block 312, Amy Street 1";
public static final String VALID_ADDRESS_BOB = "Block 123, Bobby Street 3";
public static final String VALID_ADDRESS_BLANK = "";
public static final String VALID_ADDRESS_DOMINIC = "Block 9192, Dominican Street 4";
public static final String VALID_ADDRESS_ERIC = "Avenue 4, 201/1112";
public static final String VALID_TAG_HUSBAND = "husband";
public static final String VALID_TAG_FRIEND = "friend";
public static final String VALID_TAG_NEIGHBOR = "neighbor";

public static final String NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY;
public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB;
public static final String NAME_DESC_CLIVE = " " + PREFIX_NAME + VALID_NAME_CLIVE;
public static final String NAME_DESC_DOMINIC = " " + PREFIX_NAME + VALID_NAME_DOMINIC;
public static final String NAME_DESC_ERIC = " " + PREFIX_NAME + VALID_NAME_ERIC;
public static final String PHONE_DESC_AMY = " " + PREFIX_PHONE + VALID_PHONE_AMY;
public static final String PHONE_DESC_BOB = " " + PREFIX_PHONE + VALID_PHONE_BOB;
public static final String PHONE_DESC_CLIVE = " " + PREFIX_PHONE + VALID_PHONE_CLIVE;
public static final String PHONE_DESC_DOMINIC = " " + PREFIX_PHONE + VALID_PHONE_DOMINIC;
public static final String PHONE_DESC_ERIC = " " + PREFIX_PHONE + VALID_PHONE_ERIC;
public static final String EMAIL_DESC_AMY = " " + PREFIX_EMAIL + VALID_EMAIL_AMY;
public static final String EMAIL_DESC_BOB = " " + PREFIX_EMAIL + VALID_EMAIL_BOB;
public static final String EMAIL_DESC_CLIVE = " " + PREFIX_EMAIL + VALID_EMAIL_CLIVE;
public static final String EMAIL_DESC_DOMINIC = " " + PREFIX_EMAIL + VALID_EMAIL_DOMINIC;
public static final String EMAIL_DESC_ERIC = " " + PREFIX_EMAIL + VALID_EMAIL_ERIC;
public static final String ADDRESS_DESC_AMY = " " + PREFIX_ADDRESS + VALID_ADDRESS_AMY;
public static final String ADDRESS_DESC_BOB = " " + PREFIX_ADDRESS + VALID_ADDRESS_BOB;
public static final String ADDRESS_DESC_DOMINIC = " " + PREFIX_ADDRESS + VALID_ADDRESS_DOMINIC;
public static final String ADDRESS_DESC_ERIC = " " + PREFIX_ADDRESS + VALID_ADDRESS_ERIC;
public static final String TAG_DESC_FRIEND = " " + PREFIX_TAG + VALID_TAG_FRIEND;
public static final String TAG_DESC_HUSBAND = " " + PREFIX_TAG + VALID_TAG_HUSBAND;
public static final String TAG_DESC_NEIGHBOR = " " + PREFIX_TAG + VALID_TAG_NEIGHBOR;

public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names
public static final String INVALID_PHONE_DESC = " " + PREFIX_PHONE + "911a"; // 'a' not allowed in phones
// phone numbers must be at least 2 digits
public static final String INVALID_PHONE_DESC_TOO_SHORT = " " + PREFIX_PHONE + "91";
public static final String INVALID_EMAIL_DESC = " " + PREFIX_EMAIL + "bob!yahoo"; // missing '@' symbol
public static final String INVALID_TAG_DESC = " " + PREFIX_TAG + "hubby*"; // '*' not allowed in tags
public static final String BLANK_ADDRESS_DESC = " " + PREFIX_ADDRESS + VALID_ADDRESS_BLANK;
Expand Down Expand Up @@ -132,5 +150,4 @@ public static void showPersonAtIndex(Model model, Index targetIndex) {

assertEquals(1, model.getFilteredPersonList().size());
}

}
Loading

0 comments on commit 3a8b0ed

Please sign in to comment.