Skip to content

Commit

Permalink
Merge pull request nus-cs2103-AY2223S2#120 from hingen/add-edit-command
Browse files Browse the repository at this point in the history
Add edit command
  • Loading branch information
shaowi authored Mar 18, 2023
2 parents d6fd88a + b8a496e commit d1445f1
Show file tree
Hide file tree
Showing 14 changed files with 957 additions and 677 deletions.
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;

/**
* Adds a person to the address book.
* Adds a module, lecture, or video to the tracker.
*/
public abstract class AddCommand extends Command {
public static final String COMMAND_WORD = "add";
Expand Down
244 changes: 31 additions & 213 deletions src/main/java/seedu/address/logic/commands/EditCommand.java
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 src/main/java/seedu/address/logic/commands/EditLectureCommand.java
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());
}
}
}
Loading

0 comments on commit d1445f1

Please sign in to comment.