Skip to content

Commit

Permalink
Merge pull request #62 from AriellaCallista/branch-SearchFeature
Browse files Browse the repository at this point in the history
Modify implementation of search
  • Loading branch information
AriellaCallista committed Oct 17, 2023
2 parents 37b21fb + 2cb2fba commit b256201
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 55 deletions.
47 changes: 24 additions & 23 deletions src/main/java/seedu/address/logic/commands/FindCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import static java.util.Objects.requireNonNull;

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

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.model.Model;
import seedu.address.model.person.NameContainsKeywordsPredicate;
import seedu.address.model.person.Status;
import seedu.address.model.person.StatusContainsKeywordsPredicate;
import seedu.address.model.person.Person;

/**
* Finds and lists all persons in address book whose name contains any of the argument keywords.
Expand All @@ -17,32 +18,28 @@ public class FindCommand extends Command {

public static final String COMMAND_WORD = "search";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of "
+ "the name keywords (case-insensitive) and (if specified) whose status contain any of the status"
+ "keywords (case-insensitive) and displays them as a list with index numbers.\n"
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Searches users by categories (e.g. name, status) "
+ "whose details match the given keywords (case-insensitive) "
+ "and displays them as a list with index numbers.\n"
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
+ "Example: " + COMMAND_WORD + " n/alex bernice s/interviewed";
+ "Example: " + COMMAND_WORD + " n/alex bernice st/interviewed";


private final NameContainsKeywordsPredicate namePredicate;
private final StatusContainsKeywordsPredicate statusPredicate;
private final List<Predicate<Person>> predicatesList;

/**
* Creates an FindCommand to find the specified {@code Person}
*/
public FindCommand(NameContainsKeywordsPredicate namePredicate, StatusContainsKeywordsPredicate statusPredicate) {
this.namePredicate = namePredicate;
this.statusPredicate = statusPredicate;
public FindCommand(List<Predicate<Person>> predicatesList) {
this.predicatesList = predicatesList;
}


@Override
public CommandResult execute(Model model) {
requireNonNull(model);
if (!Status.isValidStatus(statusPredicate.toString())) {
model.updateFilteredPersonList(namePredicate);
} else {
model.updateFilteredPersonList(namePredicate, statusPredicate);
}
model.updateFilteredPersonList(predicatesList);

return new CommandResult(
String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
}
Expand All @@ -59,19 +56,23 @@ public boolean equals(Object other) {
}

FindCommand otherFindCommand = (FindCommand) other;
if (Status.isValidStatus(statusPredicate.toString())) {
return namePredicate.equals(otherFindCommand.namePredicate)
&& statusPredicate.equals(otherFindCommand.statusPredicate);
Boolean isListEqual = false;
List<Predicate<Person>> otherPredicates = otherFindCommand.predicatesList;

if (predicatesList.size() != otherPredicates.size()) {
return false;
}
return namePredicate.equals(otherFindCommand.namePredicate);

for (int i = 0; i < predicatesList.size(); i++) {
isListEqual = predicatesList.get(i).equals(otherPredicates.get(i));
}
return isListEqual;
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("name predicate", namePredicate)
.add("status predicate", statusPredicate)
.add("predicates list", predicatesList)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ public CommandResult execute(Model model) {
model.sortPersonList(sortingComparator);
}

System.out.println(model.getFilteredPersonList());
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
return new CommandResult(MESSAGE_SUCCESS);
}
Expand Down
23 changes: 18 additions & 5 deletions src/main/java/seedu/address/logic/parser/FindCommandParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_STATUS;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.NameContainsKeywordsPredicate;
import seedu.address.model.person.Person;
import seedu.address.model.person.StatusContainsKeywordsPredicate;




/**
* Parses input arguments and creates a new FindCommand object
*/
Expand All @@ -30,7 +31,7 @@ public FindCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_STATUS);

if (!arePrefixesPresent(argMultimap, PREFIX_NAME)
if (!(arePrefixesPresent(argMultimap, PREFIX_NAME) || arePrefixesPresent(argMultimap, PREFIX_STATUS))
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
}
Expand All @@ -40,8 +41,20 @@ public FindCommand parse(String args) throws ParseException {
String[] nameKeywords = parseKeywordsList(argMultimap.getAllValues(PREFIX_NAME));
String[] statusKeywords = parseKeywordsList(argMultimap.getAllValues(PREFIX_STATUS));

return new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords)),
new StatusContainsKeywordsPredicate(Arrays.asList(statusKeywords)));
NameContainsKeywordsPredicate namePredicate = new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords));
StatusContainsKeywordsPredicate statusPredicate = new StatusContainsKeywordsPredicate(
Arrays.asList(statusKeywords));

List<Predicate<Person>> predicatesList = new ArrayList<>() {{
if (!nameKeywords[0].isEmpty()) {
add(namePredicate);
}
if (!statusKeywords[0].isEmpty()) {
add(statusPredicate);
}
}};

return new FindCommand(predicatesList);
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;

import javafx.collections.ObservableList;
Expand Down Expand Up @@ -89,9 +90,9 @@ public interface Model {

/**
* Updates the filter of the filtered person list to filter by the given {@code predicates}.
* @throws NullPointerException if any of the {@code predicates} is null.
* @throws NullPointerException if any of the {@code predicatesList} is null.
*/
void updateFilteredPersonList(Predicate<Person> predicate1, Predicate<Person> predicate2);
void updateFilteredPersonList(List<Predicate<Person>> predicatesList);

/**
* Sorts the filtered person list by the given {@code comparator}.
Expand Down
11 changes: 7 additions & 4 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,14 @@ public void updateFilteredPersonList(Predicate<Person> predicate) {
filteredPersons.setPredicate(predicate);
}


@Override
public void updateFilteredPersonList(Predicate<Person> predicate1, Predicate<Person> predicate2) {
requireNonNull(predicate1);
requireNonNull(predicate2);;
filteredPersons.setPredicate(person -> predicate1.test(person) && predicate2.test(person));
public void updateFilteredPersonList(List<Predicate<Person>> predicatesList) {
requireNonNull(predicatesList);
Predicate<Person> combinedPredicate = predicatesList.stream()
.reduce(Predicate::and)
.orElse(person -> true);
filteredPersons.setPredicate(combinedPredicate);
}

// TODO: fix the sorting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;

import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -161,9 +162,8 @@ public void updateFilteredPersonList(Predicate<Person> predicate) {
}

@Override
public void updateFilteredPersonList(Predicate<Person> predicate1, Predicate<Person> predicate2) {
public void updateFilteredPersonList(List<Predicate<Person>> predicatesList) {
throw new AssertionError("This method should not be called.");

}

@Override
Expand Down
25 changes: 15 additions & 10 deletions src/test/java/seedu/address/logic/commands/FindCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@

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

import org.junit.jupiter.api.Test;

import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
import seedu.address.model.person.NameContainsKeywordsPredicate;
import seedu.address.model.person.Person;
import seedu.address.model.person.StatusContainsKeywordsPredicate;

/**
Expand All @@ -39,14 +42,17 @@ public void equals() {
StatusContainsKeywordsPredicate secondStatusPredicate =
new StatusContainsKeywordsPredicate(Collections.singletonList("secondStatus"));

FindCommand findFirstCommand = new FindCommand(firstNamePredicate, firstStatusPredicate);
FindCommand findSecondCommand = new FindCommand(secondNamePredicate, secondStatusPredicate);
List<Predicate<Person>> firstPredicatesList = Arrays.asList(firstNamePredicate, firstStatusPredicate);
List<Predicate<Person>> secondPredicatesList = Arrays.asList(secondNamePredicate, secondStatusPredicate);

FindCommand findFirstCommand = new FindCommand(firstPredicatesList);
FindCommand findSecondCommand = new FindCommand(secondPredicatesList);

// same object -> returns true
assertTrue(findFirstCommand.equals(findFirstCommand));

// same values -> returns true
FindCommand findFirstCommandCopy = new FindCommand(firstNamePredicate, firstStatusPredicate);
FindCommand findFirstCommandCopy = new FindCommand(firstPredicatesList);
assertTrue(findFirstCommand.equals(findFirstCommandCopy));

// different types -> returns false
Expand All @@ -64,7 +70,7 @@ public void execute_zeroKeywords_noPersonFound() {
String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
NameContainsKeywordsPredicate namePredicate = prepareNamePredicate(" ");
StatusContainsKeywordsPredicate statusPredicate = prepareStatusPredicate("");
FindCommand command = new FindCommand(namePredicate, statusPredicate);
FindCommand command = new FindCommand(Arrays.asList(namePredicate, statusPredicate));
expectedModel.updateFilteredPersonList(namePredicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
assertEquals(Collections.emptyList(), model.getFilteredPersonList());
Expand All @@ -75,9 +81,8 @@ public void execute_multipleKeywords_multiplePersonsFound() {
String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3);
NameContainsKeywordsPredicate namePredicate = prepareNamePredicate("Kurz Elle Kunz");
StatusContainsKeywordsPredicate statusPredicate = prepareStatusPredicate("Preliminary");
FindCommand command = new FindCommand(namePredicate, statusPredicate);
expectedModel.updateFilteredPersonList(namePredicate, statusPredicate);
System.out.println(expectedModel.getAddressBook());
FindCommand command = new FindCommand(Arrays.asList(namePredicate, statusPredicate));
expectedModel.updateFilteredPersonList(Arrays.asList(namePredicate, statusPredicate));
assertCommandSuccess(command, model, expectedMessage, expectedModel);
assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredPersonList());
}
Expand All @@ -87,9 +92,9 @@ public void execute_multipleKeywords_multiplePersonsFound() {
public void toStringMethod() {
NameContainsKeywordsPredicate namePredicate = new NameContainsKeywordsPredicate(Arrays.asList("keyword"));
StatusContainsKeywordsPredicate statusPredicate = new StatusContainsKeywordsPredicate(Arrays.asList("keyword"));
FindCommand findCommand = new FindCommand(namePredicate, statusPredicate);
String expected = FindCommand.class.getCanonicalName() + "{name predicate=" + namePredicate
+ ", status predicate=" + statusPredicate + "}";
FindCommand findCommand = new FindCommand(Arrays.asList(namePredicate, statusPredicate));
String expected = FindCommand.class.getCanonicalName() + "{predicates list=[" + namePredicate + ", "
+ statusPredicate + "]}";
assertEquals(expected, findCommand.toString());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import seedu.address.model.person.NameContainsKeywordsPredicate;
import seedu.address.model.person.Person;
import seedu.address.model.person.Remark;
import seedu.address.model.person.StatusContainsKeywordsPredicate;
import seedu.address.testutil.EditPersonDescriptorBuilder;
import seedu.address.testutil.PersonBuilder;
import seedu.address.testutil.PersonUtil;
Expand Down Expand Up @@ -77,8 +76,7 @@ public void parseCommand_find() throws Exception {
List<String> keywords = Arrays.asList("foo", "bar", "baz");
FindCommand command = (FindCommand) parser.parseCommand(
FindCommand.COMMAND_WORD + " " + "n/" + keywords.stream().collect(Collectors.joining(" ")));
assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords),
new StatusContainsKeywordsPredicate(Arrays.asList(""))), command);
assertEquals(new FindCommand(Arrays.asList(new NameContainsKeywordsPredicate(keywords))), command);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public void parse_emptyArg_throwsParseException() {
public void parse_validArgs_returnsFindCommand() {
// no leading and trailing whitespaces
FindCommand expectedFindCommand =
new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob")),
new StatusContainsKeywordsPredicate(Arrays.asList("Interviewed")));
new FindCommand(Arrays.asList(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob")),
new StatusContainsKeywordsPredicate(Arrays.asList("Interviewed"))));
assertParseSuccess(parser, " n/Alice Bob st/Interviewed", expectedFindCommand);

// multiple whitespaces between keywords
Expand All @@ -37,8 +37,7 @@ public void parse_validArgs_returnsFindCommand() {
public void parse_validArgsWithNoStatus_returnsFindCommand() {
// no leading and trailing whitespaces
FindCommand expectedFindCommand =
new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob")),
new StatusContainsKeywordsPredicate(Arrays.asList("")));
new FindCommand(Arrays.asList(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))));
assertParseSuccess(parser, " n/Alice Bob", expectedFindCommand);

// multiple whitespaces between keywords
Expand Down
1 change: 0 additions & 1 deletion src/test/java/seedu/address/testutil/PersonBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ public PersonBuilder withStatus(String status) {
default:
this.status.setStatusType(StatusTypes.PRELIMINARY);
}
System.out.println(this.status);
return this;
}

Expand Down

0 comments on commit b256201

Please sign in to comment.