diff --git a/src/main/java/seedu/address/logic/commands/FindAddressCommand.java b/src/main/java/seedu/address/logic/commands/FindAddressCommand.java new file mode 100644 index 00000000000..93d89a1cbe8 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FindAddressCommand.java @@ -0,0 +1,67 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.model.Model; +import seedu.address.model.person.AddressContainsKeywordsPredicate; + +/** + * Finds and lists all persons in address book whose address contains any of the argument keywords. + * Keyword matching is case-insensitive and allows partial matching. + */ +public class FindAddressCommand extends FindCommand { + + public static final String MESSAGE_FIND_ADDRESS_PERSON_SUCCESS = "Search for address containing \"%s\" " + + " was successful. Showing results:"; + + public static final String MESSAGE_FIND_ADDRESS_PERSON_UNSUCCESSFUL = "No contacts found."; + + private final AddressContainsKeywordsPredicate predicate; + + /** + * Command to filter contacts in WedLinker based on phone numbers. + * The search matches any parts of the phone numbers. + * + * @param predicate Keywords used to filter contacts by their phone number. + */ + public FindAddressCommand(AddressContainsKeywordsPredicate predicate) { + super(); + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredPersonList(predicate); + + if (!model.getFilteredPersonList().isEmpty()) { + return new CommandResult(String.format(MESSAGE_FIND_ADDRESS_PERSON_SUCCESS, predicate.getDisplayString())); + } else { + return new CommandResult(MESSAGE_FIND_ADDRESS_PERSON_UNSUCCESSFUL); + } + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof FindAddressCommand)) { + return false; + } + + FindAddressCommand otherFindCommand = (FindAddressCommand) other; + return predicate.equals(otherFindCommand.predicate); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("predicate", predicate) + .toString(); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java index 7cfad641c40..f03db9fb28b 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindCommandParser.java @@ -11,10 +11,12 @@ import java.util.Arrays; import java.util.List; +import seedu.address.logic.commands.FindAddressCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.FindNameCommand; import seedu.address.logic.commands.FindPhoneCommand; import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.person.AddressContainsKeywordsPredicate; import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.PhoneContainsKeywordsPredicate; @@ -60,6 +62,12 @@ public FindCommand parse(String args) throws ParseException { return new FindPhoneCommand(new PhoneContainsKeywordsPredicate(phoneKeywords)); } + if (hasAddressPrefix) { + String addressInput = argMultimap.getValue(PREFIX_ADDRESS).get().trim(); // Get the actual address input + List addressKeywords = Arrays.asList(addressInput.split("\\s+")); + return new FindAddressCommand(new AddressContainsKeywordsPredicate(addressKeywords)); + } + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); } diff --git a/src/main/java/seedu/address/model/person/AddressContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/person/AddressContainsKeywordsPredicate.java new file mode 100644 index 00000000000..6ee15ccef2f --- /dev/null +++ b/src/main/java/seedu/address/model/person/AddressContainsKeywordsPredicate.java @@ -0,0 +1,48 @@ +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; + +/** + * Tests that a {@code Person}'s {@code Address} matches any of the keywords given. + */ +public class AddressContainsKeywordsPredicate implements Predicate { + private final List keywords; + + public AddressContainsKeywordsPredicate(List keywords) { + this.keywords = keywords; + } + + @Override + public boolean test(Person person) { + return keywords.stream() + .anyMatch(keyword -> StringUtil.containsPartialWordIgnoreCase(person.getAddress().value, keyword)); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof AddressContainsKeywordsPredicate)) { + return false; + } + + AddressContainsKeywordsPredicate otherNameContainsKeywordsPredicate = (AddressContainsKeywordsPredicate) other; + return keywords.equals(otherNameContainsKeywordsPredicate.keywords); + } + + @Override + public String toString() { + return new ToStringBuilder(this).add("keywords", keywords).toString(); + } + + public String getDisplayString() { + return String.join(", ", keywords); + } +}