Skip to content

Commit

Permalink
Merge pull request AY2425S1-CS2103T-F15-2#75 from JYL27/branch-FindCo…
Browse files Browse the repository at this point in the history
…mmand

Add Find Command (BACKEND)
  • Loading branch information
btbrandon authored Oct 22, 2024
2 parents 1461b43 + 3a010cf commit 1378b56
Show file tree
Hide file tree
Showing 18 changed files with 590 additions and 74 deletions.
203 changes: 137 additions & 66 deletions docs/DeveloperGuide.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/SettingUp.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: default.md
title: "Setting up and getting started"
pageNav: 3
layout: default.md
title: "Setting up and getting started"
pageNav: 3
---

# Setting up and getting started
Expand Down Expand Up @@ -52,7 +52,7 @@ If you plan to use Intellij IDEA (highly recommended):

1. **Learn the design**

When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [AddressBook’s architecture](DeveloperGuide.md#architecture).
When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [EduContacts’ architecture](DeveloperGuide.md#architecture).

1. **Do the tutorials**
These tutorials will help you get acquainted with the codebase.
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/seedu/address/logic/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public interface Logic {
/** Returns an unmodifiable view of the filtered list of persons */
ObservableList<Person> getFilteredPersonList();

/** Returns a Person object to display */
Person getPersonToDisplay();

/**
* Returns the user prefs' address book file path.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ public ObservableList<Person> getFilteredPersonList() {
return model.getFilteredPersonList();
}

@Override
public Person getPersonToDisplay() {
return model.getPersonToDisplay();
}

@Override
public Path getAddressBookFilePath() {
return model.getAddressBookFilePath();
Expand Down
92 changes: 92 additions & 0 deletions src/main/java/seedu/address/logic/commands/FindCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import java.util.List;

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.Person;
import seedu.address.model.person.StudentId;

/**
* Finds a person identified using their Student ID and displays their details.
*/
public class FindCommand extends Command {

public static final String COMMAND_WORD = "find";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Finds the student identified by the Student ID used and displays their details.\n"
+ "Parameters: "
+ "ID\n"
+ "Example: " + COMMAND_WORD + " "
+ "12345678";

public static final String MESSAGE_FIND_PERSON_SUCCESS = "Found Student: %1$s";
public static final String MESSAGE_PERSON_NOT_FOUND = "No student is found with Student ID: %1$s";
private final StudentId studentId;

/**
* Creates a FindCommand to find the person identified by the specified {@code StudentId}.
*
* @param studentId The student ID of the person to find.
* @throws NullPointerException if the {@code studentId} is null.
*/
public FindCommand(StudentId studentId) {
requireNonNull(studentId);
this.studentId = studentId;
}

/**
* Executes the find command and displays the student identified by the given studentID.
*
* @param model the model that contains the data of persons
* @return a CommandResult that shows the outcome of the command
* @throws CommandException if the studentID is invalid or not found
*/
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Person> lastShownList = model.getFilteredPersonList();
Person toFind = null;

for (Person person : lastShownList) {
if (person.getStudentId().equals(studentId)) {
toFind = person;
break;
}
}

if (toFind == null) {
throw new CommandException(String.format(MESSAGE_PERSON_NOT_FOUND, studentId));
}

model.setPersonToDisplay(toFind);
return new CommandResult(String.format(MESSAGE_FIND_PERSON_SUCCESS, Messages.format(toFind)));
}

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

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

FindCommand otherFindCommand = (FindCommand) other;
return studentId.equals(otherFindCommand.studentId);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("targetStudentId", studentId)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
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.GradeCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
Expand Down Expand Up @@ -85,6 +86,9 @@ public Command parseCommand(String userInput) throws ParseException {
case ModuleCommand.COMMAND_WORD:
return new ModuleCommandParser().parse(arguments);

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

default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/seedu/address/logic/parser/FindCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package seedu.address.logic.parser;

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

import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.StudentId;

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

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

StudentId studentId = ParserUtil.parseStudentId(trimmedArg);
return new FindCommand(studentId);
}
}
11 changes: 11 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,15 @@ public interface Model {
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredPersonList(Predicate<Person> predicate);

/**
* Displays the given person {@code personToDisplay} and their details.
* {@code target} must exist in the address book.
*/
void setPersonToDisplay(Person personToDisplay);

/**
* Returns the Person object to display.
*/
Person getPersonToDisplay();
}
41 changes: 40 additions & 1 deletion src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;

import java.nio.file.Path;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.logging.Logger;

Expand All @@ -22,6 +23,7 @@ public class ModelManager implements Model {
private final AddressBook addressBook;
private final UserPrefs userPrefs;
private final FilteredList<Person> filteredPersons;
private Person personToDisplay;

/**
* Initializes a ModelManager with the given addressBook and userPrefs.
Expand All @@ -36,6 +38,20 @@ public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs
filteredPersons = new FilteredList<>(this.addressBook.getPersonList());
}

/**
* Initializes a ModelManager with the given addressBook, userPrefs and personToDisplay.
*/
public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs, Person personToDisplay) {
requireAllNonNull(addressBook, userPrefs);

logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs);

this.addressBook = new AddressBook(addressBook);
this.userPrefs = new UserPrefs(userPrefs);
filteredPersons = new FilteredList<>(this.addressBook.getPersonList());
setPersonToDisplay(personToDisplay);
}

public ModelManager() {
this(new AddressBook(), new UserPrefs());
}
Expand Down Expand Up @@ -80,6 +96,7 @@ public void setAddressBookFilePath(Path addressBookFilePath) {
@Override
public void setAddressBook(ReadOnlyAddressBook addressBook) {
this.addressBook.resetData(addressBook);
setPersonToDisplay(null);
}

@Override
Expand All @@ -96,11 +113,16 @@ public boolean hasPerson(Person person) {
@Override
public void deletePerson(Person target) {
addressBook.removePerson(target);
if (target.isSamePerson(personToDisplay)) {
setPersonToDisplay(null);
}
}

@Override
public void addPerson(Person person) {
addressBook.addPerson(person);

setPersonToDisplay(person);
updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
}

Expand All @@ -109,6 +131,7 @@ public void setPerson(Person target, Person editedPerson) {
requireAllNonNull(target, editedPerson);

addressBook.setPerson(target, editedPerson);
setPersonToDisplay(editedPerson);
}

//=========== Filtered Person List Accessors =============================================================
Expand All @@ -128,6 +151,20 @@ public void updateFilteredPersonList(Predicate<Person> predicate) {
filteredPersons.setPredicate(predicate);
}

//=========== Person To Display =========================================================================

@Override
public void setPersonToDisplay(Person personToDisplay) {
if (personToDisplay == null || addressBook.hasPerson(personToDisplay)) {
this.personToDisplay = personToDisplay;
}
}

@Override
public Person getPersonToDisplay() {
return personToDisplay;
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand All @@ -140,9 +177,11 @@ public boolean equals(Object other) {
}

ModelManager otherModelManager = (ModelManager) other;

return addressBook.equals(otherModelManager.addressBook)
&& userPrefs.equals(otherModelManager.userPrefs)
&& filteredPersons.equals(otherModelManager.filteredPersons);
&& filteredPersons.equals(otherModelManager.filteredPersons)
&& Objects.equals(personToDisplay, otherModelManager.personToDisplay);
}

}
17 changes: 17 additions & 0 deletions src/test/java/seedu/address/logic/LogicManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException
assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredPersonList().remove(0));
}

@Test
public void getPersonToDisplay_validPerson_success() {
// store current model in a temporary variable
Model temp = model;

// set up Logic object with personToDisplay set as AMY
model.addPerson(AMY);
model = new ModelManager(model.getAddressBook(), model.getUserPrefs(), AMY);
setUp();

assertEquals(AMY, logic.getPersonToDisplay());

// reset model to old model after testing
model = temp;
}

/**
* Executes the command and confirms that
* - no exceptions are thrown <br>
Expand Down Expand Up @@ -173,6 +189,7 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath)
Person expectedPerson = new PersonBuilder(AMY).emptyModuleList().build();
ModelManager expectedModel = new ModelManager();
expectedModel.addPerson(expectedPerson);
expectedModel.setPersonToDisplay(expectedPerson);
assertCommandFailure(addCommand, CommandException.class, expectedMessage, expectedModel);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public void execute_newPerson_success() {

Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
expectedModel.addPerson(validPerson);
expectedModel.setPersonToDisplay(validPerson);

assertCommandSuccess(new AddCommand(validPerson), model,
String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validPerson)),
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/seedu/address/logic/commands/AddCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public void execute_personAcceptedByModel_addSuccessful() throws Exception {
assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validPerson)),
commandResult.getFeedbackToUser());
assertEquals(Arrays.asList(validPerson), modelStub.personsAdded);
assertEquals(validPerson, modelStub.personDisplayed);
}

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

@Override
public void setPersonToDisplay(Person personToDisplay) {
throw new AssertionError("This method should not be called.");
}

@Override
public Person getPersonToDisplay() {
throw new AssertionError("This method should not be called.");
}
}

/**
Expand All @@ -182,6 +193,7 @@ public boolean hasPerson(Person person) {
*/
private class ModelStubAcceptingPersonAdded extends ModelStub {
final ArrayList<Person> personsAdded = new ArrayList<>();
private Person personDisplayed;

@Override
public boolean hasPerson(Person person) {
Expand All @@ -193,6 +205,7 @@ public boolean hasPerson(Person person) {
public void addPerson(Person person) {
requireNonNull(person);
personsAdded.add(person);
personDisplayed = person;
}

@Override
Expand Down
Loading

0 comments on commit 1378b56

Please sign in to comment.