Skip to content

Commit

Permalink
Merge pull request #32 from CJ-Lee01/branch-delete-contacts
Browse files Browse the repository at this point in the history
Update delete contact functionality
  • Loading branch information
CJ-Lee01 authored Oct 17, 2023
2 parents f1515f8 + 3503f6e commit 8ca3b9a
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package seedu.address.commons.exceptions;

/**
* Exception thrown when attempting to make illegal.
*/
public class IllegalOperationException extends Exception {
/**
* @param message that informs the user that it has attempted an illegal operation.
*/
public IllegalOperationException(String message) {
super(message);
}

/**
* @param message that informs the user that it has attempted an illegal operation.
* @param cause of the main exception.
*/
public IllegalOperationException(String message, Throwable cause) {
super(message, cause);
}
}
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ 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_CONTACT_DISPLAYED_INDEX = "The contact index provided is invalid";
public static final String MESSAGE_NO_SUCH_CONTACT = "No such contact";
public static final String MESSAGE_CONTACTS_LISTED_OVERVIEW = "%1$d contacts listed!";
public static final String MESSAGE_DUPLICATE_FIELDS =
"Multiple values specified for the following single-valued field(s): ";
Expand Down
87 changes: 76 additions & 11 deletions src/main/java/seedu/address/logic/commands/DeleteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
import static java.util.Objects.requireNonNull;

import java.util.List;
import java.util.function.Function;

import seedu.address.commons.core.index.Index;
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.Contact;
import seedu.address.model.person.Id;

/**
* Deletes a contact identified using it's displayed index from the address book.
* Deletes a contact identified using its displayed index or its contact id from the address book.
*/
public class DeleteCommand extends Command {

Expand All @@ -25,22 +27,75 @@ public class DeleteCommand extends Command {

public static final String MESSAGE_DELETE_CONTACT_SUCCESS = "Deleted Contact: %1$s";

private final Index targetIndex;
private final Object selector; // TODO: This is very sus but this will only be used for equals comparison

private final Function<Model, Contact> contactFunction;

private final CommandException commandException;

/**
* @param targetIndex of the contact to be deleted
*/
public DeleteCommand(Index targetIndex) {
this.targetIndex = targetIndex;
this.selector = targetIndex;
this.contactFunction = (Model model) -> {
List<Contact> lastShownList = model.getFilteredContactList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
return null;
}

return lastShownList.get(targetIndex.getZeroBased());
};
this.commandException = new CommandException(Messages.MESSAGE_INVALID_CONTACT_DISPLAYED_INDEX);
}

/**
* @param targetId of the contact to be deleted
*/
public DeleteCommand(Id targetId) {
this.selector = targetId;
this.contactFunction = (Model model) -> model.getContactById(targetId);
this.commandException = new CommandException(Messages.MESSAGE_NO_SUCH_CONTACT);
}

/**
* Creates an executable DeleteCommand based on whether to delete recursively.
*
* @param targetIndex of the contact to delete in the current list
* @param shouldDeleteChildren specifies if child contacts should be deleted
*/
public static DeleteCommand selectIndex(Index targetIndex, boolean shouldDeleteChildren) {
// TODO: Add documentation to DG
requireNonNull(targetIndex);
if (shouldDeleteChildren) {
return new DeleteWithChildrenCommand(targetIndex);
}
return new DeleteCommand(targetIndex);
}

/**
* Creates an executable DeleteCommand based on whether to delete recursively.
*
* @param id of the contact to delete in the current list
* @param shouldDeleteChildren specifies if child contacts should be deleted
*/
public static DeleteCommand selectId(Id id, boolean shouldDeleteChildren) {
// TODO: Add documentation to DG
requireNonNull(id);
if (shouldDeleteChildren) {
return new DeleteWithChildrenCommand(id);
}
return new DeleteCommand(id);
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Contact> lastShownList = model.getFilteredContactList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_CONTACT_DISPLAYED_INDEX);
Contact contactToDelete = this.contactFunction.apply(model);
if (contactToDelete == null) {
throw commandException;
}

Contact contactToDelete = lastShownList.get(targetIndex.getZeroBased());
model.deleteContact(contactToDelete);
return new CommandResult(String.format(MESSAGE_DELETE_CONTACT_SUCCESS, Messages.format(contactToDelete)));
}
Expand All @@ -57,13 +112,23 @@ public boolean equals(Object other) {
}

DeleteCommand otherDeleteCommand = (DeleteCommand) other;
return targetIndex.equals(otherDeleteCommand.targetIndex);
return selector.equals(otherDeleteCommand.selector);
}

@Override
public String toString() {
// TODO: replace this toString method with sth better than targetIndex
// To not replace yet until we do the tests
return new ToStringBuilder(this)
.add("targetIndex", targetIndex)
.add("targetIndex", selector)
.toString();
}

/**
* Gives the contact that the DeleteCommand is going to delete if a model is given.
* If such a contact does not exist, gives null.
*/
protected Contact getContact(Model model) {
return contactFunction.apply(model);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import java.util.Arrays;

import seedu.address.commons.core.index.Index;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.person.Contact;
import seedu.address.model.person.Id;

/**
* Deletes a contact and also deletes its child contacts.
*/
public class DeleteWithChildrenCommand extends DeleteCommand {

public static final String MESSAGE_DELETE_CONTACT_SUCCESS = DeleteCommand.MESSAGE_DELETE_CONTACT_SUCCESS + " with"
+ ":\n%2$s";


/**
* @param targetIndex of the contact to be deleted in the current contact list
*/
public DeleteWithChildrenCommand(Index targetIndex) {
// TODO add documentation in DG
super(targetIndex);
}

public DeleteWithChildrenCommand(Id targetId) {
super(targetId);
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
Contact contactToDelete = super.getContact(model);
super.execute(model);
// At this point if the contact is null, the superclass would have thrown exception.
// Superclass would have also deleted the contact from the list.
assert contactToDelete != null;
Contact[] childContacts = contactToDelete.getChildren();
Arrays.stream(childContacts).forEach(contact -> {
model.deleteContact(contactToDelete);
});
return new CommandResult(String.format(
MESSAGE_DELETE_CONTACT_SUCCESS,
Messages.format(contactToDelete),
Arrays.stream(childContacts)
.map(c -> Messages.format(c) + "\n")
.reduce((c1, c2) -> c1 + c2)
.orElse("No other contacts found") // I can't find a better method.
));
}
}
3 changes: 1 addition & 2 deletions src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ public class CliSyntax {
public static final Flag FLAG_STATUS = new Flag("stat");
public static final Flag FLAG_POSITION = new Flag("pos");
public static final Flag FLAG_ID = new Flag("id");
public static final Flag FLAG_RECURSIVE = new Flag("recursive");
public static final Flag FLAG_ORGANIZATION_ID = new Flag("oid");



}
38 changes: 36 additions & 2 deletions src/main/java/seedu/address/logic/parser/DeleteCommandParser.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.FLAG_ID;
import static seedu.address.logic.parser.CliSyntax.FLAG_RECURSIVE;

import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.DeleteCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.Id;

/**
* Parses input arguments and creates a new DeleteCommand object
Expand All @@ -17,13 +20,44 @@ public class DeleteCommandParser implements Parser<DeleteCommand> {
* @throws ParseException if the user input does not conform the expected format
*/
public DeleteCommand parse(String args) throws ParseException {
ArgumentMultimap argumentMultimap =
ArgumentTokenizer.tokenize(args,
FLAG_ID, FLAG_RECURSIVE);

boolean hasIndex = !argumentMultimap.getPreamble().isEmpty();
boolean hasId = argumentMultimap.getValue(FLAG_ID).isPresent();
boolean isRecursive = argumentMultimap.getValue(FLAG_RECURSIVE).isPresent();

if (hasIndex) {
return parseDeleteIndexCommand(argumentMultimap.getPreamble(), isRecursive);
}

if (hasId) {
return parseDeleteIdCommand(argumentMultimap.getValue(FLAG_ID).get(), isRecursive);
}
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
}

private static DeleteCommand parseDeleteIdCommand(String idString, boolean isRecursive) throws ParseException {
Id id;
try {
Index index = ParserUtil.parseIndex(args);
return new DeleteCommand(index);
id = ParserUtil.parseId(idString);
return DeleteCommand.selectId(id, isRecursive);
} catch (ParseException pe) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE), pe);
}
}

private static DeleteCommand parseDeleteIndexCommand(String indexStr, boolean isRecursive) throws ParseException {
Index index;
try {
index = ParserUtil.parseIndex(indexStr);
return DeleteCommand.selectIndex(index, isRecursive);
} catch (ParseException pe) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE), pe);
}
}
}
16 changes: 16 additions & 0 deletions src/main/java/seedu/address/model/AddressBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.model.person.Contact;
import seedu.address.model.person.Id;
import seedu.address.model.person.UniqueContactList;

/**
Expand Down Expand Up @@ -94,6 +95,21 @@ public void removeContact(Contact key) {
contacts.remove(key);
}

/**
* Gives a contact which id matches the given id.
* Gives null if a contact with such id does not exist.
* Given id must not be null.
*/
public Contact getContactById(Id id) {
requireNonNull(id);
for (Contact c: contacts) {
if (id.equals(c.getId())) {
return c;
}
}
return null;
}

//// util methods

@Override
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.person.Contact;
import seedu.address.model.person.Id;
import seedu.address.model.person.Type;

/**
Expand Down Expand Up @@ -80,6 +81,13 @@ public interface Model {
*/
void setContact(Contact target, Contact editedContact);

/**
* Gives a contact which matches the given id.
* Gives null if no such contact is found.
* Given id must not be null.
*/
Contact getContactById(Id id);

/** Returns an unmodifiable view of the filtered contact list */
ObservableList<Contact> getFilteredContactList();

Expand Down
6 changes: 6 additions & 0 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
import seedu.address.model.person.Contact;
import seedu.address.model.person.Id;

/**
* Represents the in-memory model of the address book data.
Expand Down Expand Up @@ -111,6 +112,11 @@ public void setContact(Contact target, Contact editedContact) {
addressBook.setContact(target, editedContact);
}

@Override
public Contact getContactById(Id id) {
return addressBook.getContactById(id);
}

//=========== Filtered Contact List Accessors =============================================================

/**
Expand Down
Loading

0 comments on commit 8ca3b9a

Please sign in to comment.