Skip to content

Commit

Permalink
Add CreateHomeworkCommandParser
Browse files Browse the repository at this point in the history
Added a new class CreateHomeworkCommandParser that parses user input and creates a new CreateHomeworkCommand object. The parser validates the user input and throws a ParseException if the input does not conform to the expected format. The CreateHomeworkCommand contains a NameContainsKeywordsPredicate, a homework name, and a deadline.
  • Loading branch information
Yufannnn committed Feb 22, 2023
1 parent ae8252b commit 6a5b040
Show file tree
Hide file tree
Showing 31 changed files with 373 additions and 109 deletions.
4 changes: 2 additions & 2 deletions config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@
</module>

<module name="OperatorWrap">
<!-- Checks that the non-assignment type operator is at the next line in a line wrap.
<!-- Checks that the non-homework type operator is at the next line in a line wrap.
This includes "?", ":", "==", "!=", "/", "+", "-", "*", "%", ">>", ">>>",
">=", ">", "<<", "<=", "<", "^", "|", "||", "&", "&&", "instanceof",
"&" when used in a generic upper or lower bounds constraints,
Expand All @@ -322,7 +322,7 @@
<property name="option" value="nl"/>
</module>
<module name="OperatorWrap">
<!-- Checks that the assignment type operator is at the previous end of line in a line wrap.
<!-- Checks that the homework type operator is at the previous end of line in a line wrap.
This includes "=", "/=", "+=", "-=", "*=", "%=", ">>=", ">>>=", "<<=", "^=", "&=".
-->
<property name="tokens" value="ASSIGN, DIV_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN, STAR_ASSIGN, MOD_ASSIGN,
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/seedu/address/commons/core/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ public class Messages {

public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command";
public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The student index provided is invalid";
public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d students listed!";
public static final String MESSAGE_INVALID_STUDENT_DISPLAYED_INDEX = "The student index provided is invalid";
public static final String MESSAGE_STUDENTS_LISTED_OVERVIEW = "%1$d students listed!";

public static final String MESSAGE_HOMEWORK_ADDED_SUCCESS = "New homework added: %s, "
+ "to the following students: %s";

}
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public ReadOnlyAddressBook getAddressBook() {

@Override
public ObservableList<Student> getFilteredPersonList() {
return model.getFilteredPersonList();
return model.getFilteredStudentList();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import java.time.LocalDateTime;
import java.util.List;

import seedu.address.commons.core.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.student.Homework;
import seedu.address.model.student.NameContainsKeywordsPredicate;
import seedu.address.model.student.Student;

/**
* Adds an assignment to a student.
*/
public class CreateHomeworkCommand extends Command {

public static final String COMMAND_WORD = "assign-homework";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds an assignment to a student.\n"
+ "Parameters: "
+ "s/STUDENT_NAME "
+ "hw/HOMEWORK_NAME "
+ "d/DEADLINE\n"
+ "Example: " + COMMAND_WORD + " "
+ "s/John Doe "
+ "as/Math Homework "
+ "d/2023-03-01T12:00";

public static final String MESSAGE_SUCCESS = "New homework added: %1$s";
public static final String MESSAGE_STUDENT_NOT_FOUND = "The specified student cannot be found in the address book";

private final String homeworkName;
private final LocalDateTime deadline;
private final NameContainsKeywordsPredicate predicate;

/**
* Creates a CreateHomeworkCommand to add the specified assignment to the specified student.
*/
public CreateHomeworkCommand(NameContainsKeywordsPredicate predicate, String homeworkName, LocalDateTime deadline) {
requireNonNull(homeworkName);
requireNonNull(deadline);
requireNonNull(predicate);

this.homeworkName = homeworkName;
this.deadline = deadline;
this.predicate = predicate;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
model.updateFilteredStudentList(predicate);

List<Student> studentList = model.getFilteredStudentList();

if (deadline.isBefore(LocalDateTime.now())) {
throw new CommandException("Deadline must be in the future.");
}

Homework homework = new Homework(homeworkName, deadline);

// Add the Homework to the target student's list of Assignments
for (Student student : studentList) {
student.addHomework(homework);
}

return new CommandResult(
String.format(Messages.MESSAGE_HOMEWORK_ADDED_SUCCESS, homework, model.getFilteredStudentList()));
}


@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof CreateHomeworkCommand // instanceof handles nulls
&& predicate.equals(((CreateHomeworkCommand) other).predicate)
&& homeworkName.equals(((CreateHomeworkCommand) other).homeworkName)
&& deadline.equals(((CreateHomeworkCommand) other).deadline));
}
}
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/commands/DeleteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ public DeleteCommand(Index targetIndex) {
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Student> lastShownList = model.getFilteredPersonList();
List<Student> lastShownList = model.getFilteredStudentList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_STUDENT_DISPLAYED_INDEX);
}

Student personToDelete = lastShownList.get(targetIndex.getZeroBased());
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/seedu/address/logic/commands/EditCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) {
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Student> lastShownList = model.getFilteredPersonList();
List<Student> lastShownList = model.getFilteredStudentList();

if (index.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_STUDENT_DISPLAYED_INDEX);
}

Student personToEdit = lastShownList.get(index.getZeroBased());
Expand All @@ -82,7 +82,7 @@ public CommandResult execute(Model model) throws CommandException {
}

model.setPerson(personToEdit, editedPerson);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
model.updateFilteredStudentList(PREDICATE_SHOW_ALL_PERSONS);
return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson));
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/commands/FindCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public FindCommand(NameContainsKeywordsPredicate predicate) {
@Override
public CommandResult execute(Model model) {
requireNonNull(model);
model.updateFilteredPersonList(predicate);
model.updateFilteredStudentList(predicate);
return new CommandResult(
String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
String.format(Messages.MESSAGE_STUDENTS_LISTED_OVERVIEW, model.getFilteredStudentList().size()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class ListCommand extends Command {
@Override
public CommandResult execute(Model model) {
requireNonNull(model);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
model.updateFilteredStudentList(PREDICATE_SHOW_ALL_PERSONS);
return new CommandResult(MESSAGE_SUCCESS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.commands.ClearCommand;
import seedu.address.logic.commands.Command;
import seedu.address.logic.commands.CreateHomeworkCommand;
import seedu.address.logic.commands.DeleteCommand;
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.ExitCommand;
Expand Down Expand Up @@ -68,6 +69,9 @@ public Command parseCommand(String userInput) throws ParseException {
case HelpCommand.COMMAND_WORD:
return new HelpCommand();

case CreateHomeworkCommand.COMMAND_WORD:
return new CreateHomeworkCommandParser().parse(arguments);

default:
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ public class CliSyntax {
public static final Prefix PREFIX_EMAIL = new Prefix("e/");
public static final Prefix PREFIX_ADDRESS = new Prefix("a/");
public static final Prefix PREFIX_TAG = new Prefix("t/");
public static final Prefix PREFIX_HOMEWORK = new Prefix("hw/");
public static final Prefix PREFIX_DEADLINE = new Prefix("d/");

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package seedu.address.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DEADLINE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_HOMEWORK;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Stream;

import seedu.address.logic.commands.CreateHomeworkCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.student.NameContainsKeywordsPredicate;

/**
* Parses input arguments and creates a new CreateHomeworkCommand object
*/
public class CreateHomeworkCommandParser implements Parser<CreateHomeworkCommand> {
/**
* Parses the given {@code String} of arguments in the context of the CreateHomeworkCommand
* and returns a CreateHomeworkCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public CreateHomeworkCommand parse(String args) throws ParseException {
requireNonNull(args);

ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_HOMEWORK, PREFIX_DEADLINE);

if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_HOMEWORK, PREFIX_DEADLINE)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT,
CreateHomeworkCommand.MESSAGE_USAGE));
}

String homeworkName = argMultimap.getValue(PREFIX_HOMEWORK).get();
LocalDateTime deadline = ParserUtil.parseDeadline(argMultimap.getValue(PREFIX_DEADLINE).get());
List<String> nameKeywords = argMultimap.getAllValues(PREFIX_NAME);

return new CreateHomeworkCommand(new NameContainsKeywordsPredicate(nameKeywords),
homeworkName, deadline);
}

/**
* Returns true if all prefixes are present in the given {@code ArgumentMultimap}.
*/
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
}
43 changes: 43 additions & 0 deletions src/main/java/seedu/address/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static java.util.Objects.requireNonNull;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
Expand All @@ -22,6 +24,21 @@ public class ParserUtil {

public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer.";

//@@author Yufannn-reused
//Reused from https://github.com/RussellDash332/ip/blob/master/src/main/java/stashy/parser/Parser.java
//with minor modification, it is a pretty good way to organise and extend the acceptable date format.
private static final String[] ACCEPTABLE_DATETIME_FORMATS = {
"MMM dd yyyy HHmm", "MMM dd yyyy HH:mm",
"yyyy-MM-dd'T'HH:mm", "dd/MM/yyyy HHmm",
"dd/MM/yyyy HH:mm", "yyyy/MM/dd HHmm",
"yyyy/MM/dd HH:mm", "yyyy/MM/dd'T'HHmm",
"yyyy/MM/dd'T'HH:mm", "yyyy-MM-dd HHmm",
"yyyy-MM-dd HH:mm", "dd MMM yyyy HHmm",
"dd MMM yyyy HH:mm", "MMM dd, yyyy HHmm",
"MMM dd, yyyy HH:mm", "dd-mm-yyyy HHmm"
};
//@@author

/**
* Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be
* trimmed.
Expand Down Expand Up @@ -121,4 +138,30 @@ public static Set<Tag> parseTags(Collection<String> tags) throws ParseException
}
return tagSet;
}

//@@author Yufannnn-reused
//Reused from https://github.com/wweqg/ip/blob/master/src/main/java/duke/parser/Parser.java
//with minor modification, it is a pretty clean and concise regular expression for general instructions
/**
* Parses a string to a LocalDateTime object using the acceptable date time formats defined
* in {@link #ACCEPTABLE_DATETIME_FORMATS}.
*
* @param date The date string to be parsed
* @return The parsed LocalDateTime object
* @throws ParseException if the date string does not match any of the acceptable date time formats
*/
public static LocalDateTime parseDeadline(String date) throws ParseException {
for (String dateTimeFormat : ACCEPTABLE_DATETIME_FORMATS) {
try {
return LocalDateTime.parse(date,
DateTimeFormatter.ofPattern(dateTimeFormat));
} catch (Exception e) {
// Go to the next dateTimeFormat
}
}

throw new ParseException("Invalid date format. Please use one of the following formats:\n"
+ String.join("\n", ACCEPTABLE_DATETIME_FORMATS));
}
//@@author
}
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ public interface Model {
void setPerson(Student target, Student editedPerson);

/** Returns an unmodifiable view of the filtered person list */
ObservableList<Student> getFilteredPersonList();
ObservableList<Student> getFilteredStudentList();

/**
* Updates the filter of the filtered person list to filter by the given {@code predicate}.
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredPersonList(Predicate<Student> predicate);
void updateFilteredStudentList(Predicate<Student> predicate);
}
6 changes: 3 additions & 3 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void deletePerson(Student target) {
@Override
public void addPerson(Student person) {
addressBook.addPerson(person);
updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
updateFilteredStudentList(PREDICATE_SHOW_ALL_PERSONS);
}

@Override
Expand All @@ -118,12 +118,12 @@ public void setPerson(Student target, Student editedPerson) {
* {@code versionedAddressBook}
*/
@Override
public ObservableList<Student> getFilteredPersonList() {
public ObservableList<Student> getFilteredStudentList() {
return filteredPersons;
}

@Override
public void updateFilteredPersonList(Predicate<Student> predicate) {
public void updateFilteredStudentList(Predicate<Student> predicate) {
requireNonNull(predicate);
filteredPersons.setPredicate(predicate);
}
Expand Down

This file was deleted.

Loading

0 comments on commit 6a5b040

Please sign in to comment.