forked from nus-cs2103-AY2223S2/tp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request nus-cs2103-AY2223S2#120 from hingen/add-edit-command
Add edit command
- Loading branch information
Showing
14 changed files
with
957 additions
and
677 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
244 changes: 31 additions & 213 deletions
244
src/main/java/seedu/address/logic/commands/EditCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,226 +1,44 @@ | ||
package seedu.address.logic.commands; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; | ||
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; | ||
import static seedu.address.logic.parser.CliSyntax.PREFIX_CODE; | ||
import static seedu.address.logic.parser.CliSyntax.PREFIX_LECTURE; | ||
import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE; | ||
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; | ||
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; | ||
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; | ||
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; | ||
|
||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
import seedu.address.commons.core.Messages; | ||
import seedu.address.commons.core.index.Index; | ||
import seedu.address.commons.util.CollectionUtil; | ||
import seedu.address.logic.commands.exceptions.CommandException; | ||
import seedu.address.model.Model; | ||
import seedu.address.model.person.Address; | ||
import seedu.address.model.person.Email; | ||
import seedu.address.model.person.Name; | ||
import seedu.address.model.person.Person; | ||
import seedu.address.model.person.Phone; | ||
import seedu.address.model.tag.Tag; | ||
|
||
/** | ||
* Edits the details of an existing person in the address book. | ||
* Edits the details of a module, lecture, or video in the tracker. | ||
*/ | ||
public class EditCommand extends Command { | ||
public abstract class EditCommand extends Command { | ||
|
||
public static final String COMMAND_WORD = "edit"; | ||
|
||
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the person identified " | ||
+ "by the index number used in the displayed person list. " | ||
+ "Existing values will be overwritten by the input values.\n" | ||
+ "Parameters: INDEX (must be a positive integer) " | ||
+ "[" + PREFIX_NAME + "NAME] " | ||
+ "[" + PREFIX_PHONE + "PHONE] " | ||
+ "[" + PREFIX_EMAIL + "EMAIL] " | ||
+ "[" + PREFIX_ADDRESS + "ADDRESS] " | ||
+ "[" + PREFIX_TAG + "TAG]...\n" | ||
+ "Example: " + COMMAND_WORD + " 1 " | ||
+ PREFIX_PHONE + "91234567 " | ||
+ PREFIX_EMAIL + "[email protected]"; | ||
public static final String MESSAGE_USAGE = COMMAND_WORD + ": (1) Edits the details of a module in the tracker. " | ||
+ "Parameters: " | ||
+ "{module_code} " | ||
+ "[" + PREFIX_CODE + " {new_code}] " | ||
+ "[" + PREFIX_NAME + " {new_name}] " | ||
+ "Example: " + COMMAND_WORD + " CS2040S " | ||
+ PREFIX_CODE + " CS2040 " | ||
+ PREFIX_NAME + " Data Structures & Algorithms | " | ||
+ "(2) Edits the details of a lecture in a module. " | ||
+ "Parameters: " | ||
+ "{lecture_name} " | ||
+ "[" + PREFIX_MODULE + " {module_code}] " | ||
+ "[" + PREFIX_NAME + " {new_name}] " | ||
+ "Example: " + COMMAND_WORD + " Lecture 01 " | ||
+ PREFIX_MODULE + " CS2040S " | ||
+ PREFIX_NAME + " Lecture 01 Introduction | " | ||
+ "(3) Edits the details of a video in a lecture. " | ||
+ "Parameters: " | ||
+ "{video_name} " | ||
+ "[" + PREFIX_MODULE + " {module_code}] " | ||
+ "[" + PREFIX_LECTURE + " {lecture_name}] " | ||
+ "[" + PREFIX_NAME + " {new_name}] " | ||
+ "Example: " + COMMAND_WORD + " Video 01 " | ||
+ PREFIX_MODULE + " CS2040S " | ||
+ PREFIX_LECTURE + " Lecture 01 " | ||
+ PREFIX_NAME + " Video 01 Grade Breakdown"; | ||
|
||
public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s"; | ||
public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided."; | ||
public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book."; | ||
|
||
private final Index index; | ||
private final EditPersonDescriptor editPersonDescriptor; | ||
|
||
/** | ||
* @param index of the person in the filtered person list to edit | ||
* @param editPersonDescriptor details to edit the person with | ||
*/ | ||
public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) { | ||
requireNonNull(index); | ||
requireNonNull(editPersonDescriptor); | ||
|
||
this.index = index; | ||
this.editPersonDescriptor = new EditPersonDescriptor(editPersonDescriptor); | ||
} | ||
|
||
@Override | ||
public CommandResult execute(Model model) throws CommandException { | ||
requireNonNull(model); | ||
List<Person> lastShownList = model.getFilteredPersonList(); | ||
|
||
if (index.getZeroBased() >= lastShownList.size()) { | ||
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); | ||
} | ||
|
||
Person personToEdit = lastShownList.get(index.getZeroBased()); | ||
Person editedPerson = createEditedPerson(personToEdit, editPersonDescriptor); | ||
|
||
if (!personToEdit.isSamePerson(editedPerson) && model.hasPerson(editedPerson)) { | ||
throw new CommandException(MESSAGE_DUPLICATE_PERSON); | ||
} | ||
|
||
model.setPerson(personToEdit, editedPerson); | ||
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); | ||
return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson)); | ||
} | ||
|
||
/** | ||
* Creates and returns a {@code Person} with the details of {@code personToEdit} | ||
* edited with {@code editPersonDescriptor}. | ||
*/ | ||
private static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) { | ||
assert personToEdit != null; | ||
|
||
Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName()); | ||
Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone()); | ||
Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail()); | ||
Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); | ||
Set<Tag> updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); | ||
|
||
return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
// short circuit if same object | ||
if (other == this) { | ||
return true; | ||
} | ||
|
||
// instanceof handles nulls | ||
if (!(other instanceof EditCommand)) { | ||
return false; | ||
} | ||
|
||
// state check | ||
EditCommand e = (EditCommand) other; | ||
return index.equals(e.index) | ||
&& editPersonDescriptor.equals(e.editPersonDescriptor); | ||
} | ||
|
||
/** | ||
* Stores the details to edit the person with. Each non-empty field value will replace the | ||
* corresponding field value of the person. | ||
*/ | ||
public static class EditPersonDescriptor { | ||
private Name name; | ||
private Phone phone; | ||
private Email email; | ||
private Address address; | ||
private Set<Tag> tags; | ||
|
||
public EditPersonDescriptor() {} | ||
|
||
/** | ||
* Copy constructor. | ||
* A defensive copy of {@code tags} is used internally. | ||
*/ | ||
public EditPersonDescriptor(EditPersonDescriptor toCopy) { | ||
setName(toCopy.name); | ||
setPhone(toCopy.phone); | ||
setEmail(toCopy.email); | ||
setAddress(toCopy.address); | ||
setTags(toCopy.tags); | ||
} | ||
|
||
/** | ||
* Returns true if at least one field is edited. | ||
*/ | ||
public boolean isAnyFieldEdited() { | ||
return CollectionUtil.isAnyNonNull(name, phone, email, address, tags); | ||
} | ||
|
||
public void setName(Name name) { | ||
this.name = name; | ||
} | ||
|
||
public Optional<Name> getName() { | ||
return Optional.ofNullable(name); | ||
} | ||
|
||
public void setPhone(Phone phone) { | ||
this.phone = phone; | ||
} | ||
|
||
public Optional<Phone> getPhone() { | ||
return Optional.ofNullable(phone); | ||
} | ||
|
||
public void setEmail(Email email) { | ||
this.email = email; | ||
} | ||
|
||
public Optional<Email> getEmail() { | ||
return Optional.ofNullable(email); | ||
} | ||
|
||
public void setAddress(Address address) { | ||
this.address = address; | ||
} | ||
|
||
public Optional<Address> getAddress() { | ||
return Optional.ofNullable(address); | ||
} | ||
|
||
/** | ||
* Sets {@code tags} to this object's {@code tags}. | ||
* A defensive copy of {@code tags} is used internally. | ||
*/ | ||
public void setTags(Set<Tag> tags) { | ||
this.tags = (tags != null) ? new HashSet<>(tags) : null; | ||
} | ||
|
||
/** | ||
* Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException} | ||
* if modification is attempted. | ||
* Returns {@code Optional#empty()} if {@code tags} is null. | ||
*/ | ||
public Optional<Set<Tag>> getTags() { | ||
return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
// short circuit if same object | ||
if (other == this) { | ||
return true; | ||
} | ||
|
||
// instanceof handles nulls | ||
if (!(other instanceof EditPersonDescriptor)) { | ||
return false; | ||
} | ||
|
||
// state check | ||
EditPersonDescriptor e = (EditPersonDescriptor) other; | ||
|
||
return getName().equals(e.getName()) | ||
&& getPhone().equals(e.getPhone()) | ||
&& getEmail().equals(e.getEmail()) | ||
&& getAddress().equals(e.getAddress()) | ||
&& getTags().equals(e.getTags()); | ||
} | ||
} | ||
} |
129 changes: 129 additions & 0 deletions
129
src/main/java/seedu/address/logic/commands/EditLectureCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package seedu.address.logic.commands; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
import static seedu.address.commons.core.Messages.MESSAGE_LECTURE_DOES_NOT_EXIST; | ||
import static seedu.address.commons.core.Messages.MESSAGE_MODULE_DOES_NOT_EXIST; | ||
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
import seedu.address.logic.commands.exceptions.CommandException; | ||
import seedu.address.model.Model; | ||
import seedu.address.model.lecture.Lecture; | ||
import seedu.address.model.lecture.LectureName; | ||
import seedu.address.model.lecture.ReadOnlyLecture; | ||
import seedu.address.model.module.ModuleCode; | ||
import seedu.address.model.module.ReadOnlyModule; | ||
import seedu.address.model.tag.Tag; | ||
import seedu.address.model.video.Video; | ||
|
||
/** | ||
* Edits the details of a lecture in a module. | ||
*/ | ||
public class EditLectureCommand extends EditCommand { | ||
|
||
public static final String MESSAGE_SUCCESS = "Edited lecture of module %s: %s"; | ||
public static final String MESSAGE_DUPLICATE_LECTURE = "This lecture already exists in %s."; | ||
|
||
private final ModuleCode moduleCode; | ||
private final LectureName lectureName; | ||
private final EditLectureDescriptor editLectureDescriptor; | ||
|
||
/** | ||
* Creates an {@code EditLectureCommand} to edit the details of a lecture whose name is {@code lectureName} in | ||
* the module whose code is {@code moduleCode}. | ||
* | ||
* @param moduleCode The code of the module containing the lecture. | ||
* @param lectureName The name of the lecture to be edited. | ||
* @param editLectureDescriptor The details to edit the lecture with. | ||
*/ | ||
public EditLectureCommand(ModuleCode moduleCode, LectureName lectureName, | ||
EditLectureDescriptor editLectureDescriptor) { | ||
|
||
requireAllNonNull(moduleCode, lectureName, editLectureDescriptor); | ||
|
||
this.moduleCode = moduleCode; | ||
this.lectureName = lectureName; | ||
this.editLectureDescriptor = editLectureDescriptor; | ||
} | ||
|
||
@Override | ||
public CommandResult execute(Model model) throws CommandException { | ||
requireNonNull(model); | ||
|
||
if (!model.hasModule(moduleCode)) { | ||
throw new CommandException(String.format(MESSAGE_MODULE_DOES_NOT_EXIST, moduleCode)); | ||
} | ||
|
||
ReadOnlyModule module = model.getTracker().getModule(moduleCode); | ||
|
||
if (!model.hasLecture(moduleCode, lectureName)) { | ||
throw new CommandException(String.format(MESSAGE_LECTURE_DOES_NOT_EXIST, lectureName, moduleCode)); | ||
} | ||
|
||
ReadOnlyLecture lectureToEdit = module.getLecture(lectureName); | ||
Lecture editedLecture = createEditedLecture(lectureToEdit); | ||
|
||
if (!lectureToEdit.isSameLecture(editedLecture) && model.hasLecture(module, editedLecture)) { | ||
throw new CommandException(String.format(MESSAGE_DUPLICATE_LECTURE, moduleCode)); | ||
} | ||
|
||
model.setLecture(module, lectureToEdit, editedLecture); | ||
return new CommandResult(String.format(MESSAGE_SUCCESS, moduleCode, editedLecture)); | ||
} | ||
|
||
private Lecture createEditedLecture(ReadOnlyLecture lectureToEdit) { | ||
requireNonNull(lectureToEdit); | ||
|
||
LectureName updatedName = editLectureDescriptor.getName().orElse(lectureToEdit.getName()); | ||
|
||
Set<Tag> tags = lectureToEdit.getTags(); | ||
List<Video> videos = lectureToEdit.getVideoList(); | ||
|
||
return new Lecture(updatedName, tags, videos); | ||
} | ||
|
||
/** | ||
* Stores the details to edit the lecture with.<p> | ||
* Each non-empty field value will replace the corresponding field value of the lecture. | ||
*/ | ||
public static class EditLectureDescriptor { | ||
private LectureName name; | ||
|
||
public EditLectureDescriptor() {} | ||
|
||
/** | ||
* Copy constructor. | ||
* | ||
* @param toCopy The {@code EditLectureDescriptor} to copy. | ||
*/ | ||
public EditLectureDescriptor(EditLectureDescriptor toCopy) { | ||
setName(toCopy.name); | ||
} | ||
|
||
public Optional<LectureName> getName() { | ||
return Optional.ofNullable(name); | ||
} | ||
|
||
public void setName(LectureName name) { | ||
this.name = name; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
if (other == this) { | ||
return true; | ||
} | ||
|
||
if (!(other instanceof EditLectureDescriptor)) { | ||
return false; | ||
} | ||
|
||
EditLectureDescriptor descriptor = (EditLectureDescriptor) other; | ||
|
||
return getName().equals(descriptor.getName()); | ||
} | ||
} | ||
} |
Oops, something went wrong.