Skip to content

Commit

Permalink
Merge pull request #86 from leezhixuan/branchRevampFind
Browse files Browse the repository at this point in the history
Revamp Find
  • Loading branch information
leezhixuan authored Oct 21, 2021
2 parents 7e817fa + 2f72353 commit 127cf7b
Show file tree
Hide file tree
Showing 13 changed files with 813 additions and 41 deletions.
24 changes: 13 additions & 11 deletions src/main/java/seedu/address/logic/commands/FindCommand.java
Original file line number Diff line number Diff line change
@@ -1,42 +1,44 @@
package seedu.address.logic.commands;


import static java.util.Objects.requireNonNull;

import seedu.address.commons.core.Messages;
import seedu.address.model.Model;
import seedu.address.model.person.NameContainsKeywordsPredicate;
import seedu.address.model.person.FindPredicate;


/**
* Finds and lists all persons in address book whose name contains any of the argument keywords.
* Finds and lists all persons in address book whose details contain ALL of the argument keywords provided.
* Keyword matching is case insensitive.
*/
public class FindCommand extends Command {

public static final String COMMAND_WORD = "find";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of "
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain ALL of "
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
+ "Example: " + COMMAND_WORD + " alice bob charlie";
+ "Parameters: n/[name] ... t/[tag] ...\n"
+ "Example: " + COMMAND_WORD + " n/alice n/bob t/friends t/colleagues";

private final NameContainsKeywordsPredicate predicate;
private final FindPredicate findPredicate;

public FindCommand(NameContainsKeywordsPredicate predicate) {
this.predicate = predicate;
public FindCommand(FindPredicate findPredicate) {
this.findPredicate = findPredicate;
}

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

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof FindCommand // instanceof handles nulls
&& predicate.equals(((FindCommand) other).predicate)); // state check
|| ((other instanceof FindCommand) // instanceof handles nulls
&& findPredicate.equals(((FindCommand) other).findPredicate)); // state check
}
}
43 changes: 43 additions & 0 deletions src/main/java/seedu/address/logic/commands/FindOrCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import seedu.address.commons.core.Messages;
import seedu.address.model.Model;
import seedu.address.model.person.FindOrPredicate;


/**
* Finds and lists all persons in address book whose name contains ANY of the argument keywords provided.
* Keyword matching is case insensitive.
*/
public class FindOrCommand extends Command {

public static final String COMMAND_WORD = "findOr";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain ANY of "
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
+ "Parameters: n/[name] ... t/[tag] ...\n"
+ "Example: " + COMMAND_WORD + " n/alice n/bob t/friends t/colleagues";

private final FindOrPredicate findOrPredicate;

public FindOrCommand(FindOrPredicate findOrPredicate) {
this.findOrPredicate = findOrPredicate;
}

@Override
public CommandResult execute(Model model) {
requireNonNull(model);
model.updateFilteredPersonList(findOrPredicate);
return new CommandResult(
String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| ((other instanceof FindOrCommand) // instanceof handles nulls
&& findOrPredicate.equals(((FindOrCommand) other).findOrPredicate)); // state check
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.FindOrCommand;
import seedu.address.logic.commands.FindTagCaseInsensitiveCommand;
import seedu.address.logic.commands.FindTagCaseSensitiveCommand;
import seedu.address.logic.commands.HelpCommand;
Expand Down Expand Up @@ -73,6 +74,9 @@ public Command parseCommand(String userInput) throws ParseException {
case FindCommand.COMMAND_WORD:
return new FindCommandParser().parse(arguments);

case FindOrCommand.COMMAND_WORD:
return new FindOrCommandParser().parse(arguments);

case ListCommand.COMMAND_WORD:
return new ListCommand();

Expand Down
28 changes: 23 additions & 5 deletions src/main/java/seedu/address/logic/parser/FindCommandParser.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package seedu.address.logic.parser;

import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.NameContainsKeywordsPredicate;
import seedu.address.model.person.FindPredicate;
import seedu.address.model.person.Name;
import seedu.address.model.tag.Tag;

/**
* Parses input arguments and creates a new FindCommand object
Expand All @@ -25,9 +30,22 @@ public FindCommand parse(String args) throws ParseException {
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
}

String[] nameKeywords = trimmedArgs.split("\\s+");
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_TAG);
List<String> nameStringList = argMultimap.getAllValues(PREFIX_NAME);
List<String> tagStringList = argMultimap.getAllValues(PREFIX_TAG);

List<Name> nameKeywords;
List<Tag> tagList;
try {
nameKeywords = nameStringList.stream().map(Name::new).collect(Collectors.toList());
tagList = tagStringList.stream().map(Tag::new).collect(Collectors.toList());
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage());
}

return new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords)));
}
FindPredicate findpredicate = new FindPredicate(nameKeywords, tagList);

return new FindCommand(findpredicate);
}
}
54 changes: 54 additions & 0 deletions src/main/java/seedu/address/logic/parser/FindOrCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package seedu.address.logic.parser;

import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;

import java.util.List;
import java.util.stream.Collectors;

import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.FindOrCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.FindOrPredicate;
import seedu.address.model.person.Name;
import seedu.address.model.tag.Tag;

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

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

if (trimmedArgs.isEmpty()) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
}

ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_TAG);
List<String> nameStringList = argMultimap.getAllValues(PREFIX_NAME);
List<String> tagStringList = argMultimap.getAllValues(PREFIX_TAG);

List<Name> nameKeywords;
List<Tag> tagList;
try {
nameKeywords = nameStringList.stream().map(Name::new).collect(Collectors.toList());
tagList = tagStringList.stream().map(Tag::new).collect(Collectors.toList());
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage());
}

FindOrPredicate findOrPredicate = new FindOrPredicate(nameKeywords, tagList);
return new FindOrCommand(findOrPredicate);
}

}

52 changes: 52 additions & 0 deletions src/main/java/seedu/address/model/person/FindOrPredicate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package seedu.address.model.person;

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

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

/**
* Tests that a {@code Person}'s {@code Name} OR {@code Tag} matches ANY of the keywords given.
*/
public class FindOrPredicate implements Predicate<Person> {

private final List<Name> nameList;
private final List<Tag> tagList;

/**
* Creates a FindOrPredicate
*
* @param nameList refers to the list of Names to be searched for
* @param tagList refers to the list of Tags to be searched for
*/
public FindOrPredicate(List<Name> nameList, List<Tag> tagList) {
this.nameList = nameList;
this.tagList = tagList;
}

@Override
public boolean test(Person person) {
Tag[] arrayTags = new Tag[person.getTags().toArray().length];
if (!nameList.isEmpty()) {
return nameList.stream()
.anyMatch(name -> StringUtil.containsWordIgnoreCase(person.getName().fullName, name.fullName))
|| tagList.stream()
.anyMatch(tag -> Arrays.stream(person.getTags().toArray(arrayTags))
.anyMatch(personTag -> personTag.compareTag(tag, false)));
} else {
return tagList.stream()
.anyMatch(tag -> Arrays.stream(person.getTags().toArray(arrayTags))
.anyMatch(personTag -> personTag.compareTag(tag, false)));
}
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof FindOrPredicate) // instanceof handles nulls
&& (nameList.equals(((FindOrPredicate) other).nameList)
&& tagList.equals(((FindOrPredicate) other).tagList)); // state check
}
}
47 changes: 47 additions & 0 deletions src/main/java/seedu/address/model/person/FindPredicate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package seedu.address.model.person;

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

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


/**
* Tests that a {@code Person}'s {@code Name} AND {@code Tag} matches ALL of the keywords given.
*/
public class FindPredicate implements Predicate<Person> {

private final List<Name> nameList;
private final List<Tag> tagList;

/**
* Creates a FindPredicate
*
* @param nameList refers to the list of Names to be searched for
* @param tagList refers to the list of Tags to be searched for
*/
public FindPredicate(List<Name> nameList, List<Tag> tagList) {
this.nameList = nameList;
this.tagList = tagList;
}

@Override
public boolean test(Person person) {
Tag[] arrayTags = new Tag[person.getTags().toArray().length];
return nameList.stream()
.allMatch(name -> StringUtil.containsWordIgnoreCase(person.getName().fullName, name.fullName))
&& tagList.stream()
.allMatch(tag -> Arrays.stream(person.getTags().toArray(arrayTags))
.anyMatch(personTag-> personTag.compareTag(tag, false)));
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof FindPredicate) // instanceof handles nulls
&& (nameList.equals(((FindPredicate) other).nameList)
&& tagList.equals(((FindPredicate) other).tagList)); // state check
}
}
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/ui/BirthdayReminderCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public BirthdayReminderCard(Person person) {
phone.setText(person.getPhoneNumber());
Optional<Birthday> possibleBirthday = person.getBirthday();
assert possibleBirthday.isPresent();
birthday.setText(possibleBirthday.map(Birthday::display).get());
birthday.setText(possibleBirthday.map(Birthday::display).orElse(""));
}

@Override
Expand Down
Loading

0 comments on commit 127cf7b

Please sign in to comment.