Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update command added #21

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 226 additions & 24 deletions src/seedu/addressbook/AddressBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,7 @@
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Scanner;
import java.util.Set;
import java.util.*;

/*
* NOTE : =============================================================
Expand Down Expand Up @@ -71,6 +64,7 @@ public class AddressBook {
private static final String MESSAGE_COMMAND_HELP_PARAMETERS = "\tParameters: %1$s";
private static final String MESSAGE_COMMAND_HELP_EXAMPLE = "\tExample: %1$s";
private static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s";
private static final String MESSAGE_UPDATE_PERSON_SUCCESS = "Updated person: %1$s";
private static final String MESSAGE_DISPLAY_PERSON_DATA = "%1$s Phone Number: %2$s Email: %3$s";
private static final String MESSAGE_DISPLAY_LIST_ELEMENT_INDEX = "%1$d. ";
private static final String MESSAGE_GOODBYE = "Exiting Address Book... Good bye!";
Expand Down Expand Up @@ -105,6 +99,13 @@ public class AddressBook {
+ PERSON_DATA_PREFIX_EMAIL + "EMAIL";
private static final String COMMAND_ADD_EXAMPLE = COMMAND_ADD_WORD + " John Doe p/98765432 e/[email protected]";

private static final String COMMAND_UPDATE_WORD = "update";
private static final String COMMAND_UPDATE_DESC = "Update a person's phone number or email address";
private static final String COMMAND_UPDATE_PARAMETERS = "INDEX (Optional)"
+ PERSON_DATA_PREFIX_PHONE + "NEW PHONE NUMBER (Optional)"
+ PERSON_DATA_PREFIX_EMAIL + "NEW EMAIL";
private static final String COMMAND_UPDATE_EXAMPLE = COMMAND_UPDATE_WORD + "1 p/12345678";

private static final String COMMAND_FIND_WORD = "find";
private static final String COMMAND_FIND_DESC = "Finds all persons whose names contain any of the specified "
+ "keywords (case-sensitive) and displays them as a list with index numbers.";
Expand Down Expand Up @@ -369,22 +370,24 @@ private static String executeCommand(String userInputString) {
final String commandType = commandTypeAndParams[0];
final String commandArgs = commandTypeAndParams[1];
switch (commandType) {
case COMMAND_ADD_WORD:
return executeAddPerson(commandArgs);
case COMMAND_FIND_WORD:
return executeFindPersons(commandArgs);
case COMMAND_LIST_WORD:
return executeListAllPersonsInAddressBook();
case COMMAND_DELETE_WORD:
return executeDeletePerson(commandArgs);
case COMMAND_CLEAR_WORD:
return executeClearAddressBook();
case COMMAND_HELP_WORD:
return getUsageInfoForAllCommands();
case COMMAND_EXIT_WORD:
executeExitProgramRequest();
default:
return getMessageForInvalidCommandInput(commandType, getUsageInfoForAllCommands());
case COMMAND_ADD_WORD:
return executeAddPerson(commandArgs);
case COMMAND_FIND_WORD:
return executeFindPersons(commandArgs);
case COMMAND_LIST_WORD:
return executeListAllPersonsInAddressBook();
case COMMAND_DELETE_WORD:
return executeDeletePerson(commandArgs);
case COMMAND_CLEAR_WORD:
return executeClearAddressBook();
case COMMAND_HELP_WORD:
return getUsageInfoForAllCommands();
case COMMAND_EXIT_WORD:
executeExitProgramRequest();
case COMMAND_UPDATE_WORD:
return executeUpdatePerson(commandArgs);
default:
return getMessageForInvalidCommandInput(commandType, getUsageInfoForAllCommands());
}
}

Expand Down Expand Up @@ -558,6 +561,181 @@ private static String getMessageForSuccessfulDelete(String[] deletedPerson) {
return String.format(MESSAGE_DELETE_PERSON_SUCCESS, getMessageForFormattedPersonData(deletedPerson));
}

/**
* Updates person identified using last displayed index.
*
* @param commandArgs full command args string from the user
* @return feedback display message for the operation result
*/
private static String executeUpdatePerson(String commandArgs) {
if (!isUpdatePersonArgsValid(commandArgs)) {
return getMessageForInvalidCommandInput(COMMAND_DELETE_WORD, getUsageInfoForDeleteCommand());
}
final int targetVisibleIndex = extractTargetIndexFromUpdatePersonArgs(commandArgs);
if (!isDisplayIndexValidForLastPersonListingView(targetVisibleIndex)) {
return MESSAGE_INVALID_PERSON_DISPLAYED_INDEX;
}
final String[] targetInModel = getPersonByLastVisibleIndex(targetVisibleIndex);
if (isPhoneChanging(commandArgs)){
Optional<String> newPhone = getNewPhone(commandArgs);
if (!newPhone.isPresent()){
return getMessageForInvalidCommandInput(COMMAND_UPDATE_WORD, getUsageInfoForUpdateCommand());
}
if (!updatePersonFromAddressbook(targetInModel, PERSON_DATA_INDEX_PHONE, newPhone.get())){
return MESSAGE_PERSON_NOT_IN_ADDRESSBOOK;
}
}
if (isEmailChanging(commandArgs)){
Optional<String> newEmail = getNewEmail(commandArgs);
if (!newEmail.isPresent()){
return getMessageForInvalidCommandInput(COMMAND_UPDATE_WORD, getUsageInfoForUpdateCommand());
}
if (!updatePersonFromAddressbook(targetInModel, PERSON_DATA_INDEX_EMAIL, newEmail.get())){
return MESSAGE_PERSON_NOT_IN_ADDRESSBOOK;
}
}
return getMessageForSuccessfulUpdate(targetInModel); // success
}

/**
* Checks if the index of person to update is valid and there is at least one field to update
* @param rawArgs full command from the user
* @return whether the command is valid
*/
private static boolean isUpdatePersonArgsValid(String rawArgs) {
final ArrayList<OptionalInt> indexsOfPrefixs = extractPrefixIndexFromUpdatePersonArgs(rawArgs);
if (!indexsOfPrefixs.get(0).isPresent()){
return false;
}
final int indexOfFirstPrefix = indexsOfPrefixs.get(0).getAsInt();
try {
final int extractedIndex = Integer.parseInt(rawArgs.substring(0, indexOfFirstPrefix).trim()); // use standard libraries to parse
return extractedIndex >= DISPLAYED_INDEX_OFFSET;
} catch (NumberFormatException nfe) {
return false;
}
}

/**
* Extracts the indexes of prefix_phone and prefix_email
* @param rawArgs full command from the user
* @return An Arraylist of OptionalInt describing the indexes of prefixes
*/
public static ArrayList<OptionalInt> extractPrefixIndexFromUpdatePersonArgs(String rawArgs){
int indexOfFirstPrefix = -1;
ArrayList<OptionalInt> indexOfPrefixs = new ArrayList<>();
final int indexOfPhonePrefix = rawArgs.indexOf(PERSON_DATA_PREFIX_PHONE);
if (indexOfPhonePrefix != -1){
indexOfFirstPrefix = indexOfPhonePrefix;
}
final int indexOfEmailPrefix = rawArgs.indexOf(PERSON_DATA_PREFIX_EMAIL);
if (indexOfEmailPrefix != -1 && (indexOfEmailPrefix < indexOfFirstPrefix || indexOfFirstPrefix == -1)){
indexOfFirstPrefix = indexOfEmailPrefix;
}
if (indexOfFirstPrefix == -1){
indexOfPrefixs.add(OptionalInt.empty());
indexOfPrefixs.add(OptionalInt.empty());
} else {
indexOfPrefixs.add(OptionalInt.of(indexOfFirstPrefix));
if (indexOfEmailPrefix == -1 || indexOfPhonePrefix == -1){
indexOfPrefixs.add(OptionalInt.empty());
} else {
indexOfPrefixs.add(OptionalInt.of(Math.max(indexOfEmailPrefix, indexOfPhonePrefix)));
}
}
return indexOfPrefixs;
}

/**
* Extract the index of person to update
* @param rawArgs full command from the user
* @return the index of person to update
*/
private static int extractTargetIndexFromUpdatePersonArgs(String rawArgs) {
final ArrayList<OptionalInt> indexsOfPrefixs = extractPrefixIndexFromUpdatePersonArgs(rawArgs);
final int indexOfFirstPrefix = indexsOfPrefixs.get(0).getAsInt();
return Integer.parseInt(rawArgs.substring(0, indexOfFirstPrefix).trim());
}

/**
* Check if the command requires phone number to be changed
* @param rawArgs full command from the user
* @return whether phont number is to be changed
*/
private static boolean isPhoneChanging(String rawArgs){
final int indexOfPhonePrefix = rawArgs.indexOf(PERSON_DATA_PREFIX_PHONE);
return (indexOfPhonePrefix != -1);
}

/**
* Extract the new phone number
* @param rawArgs full command from the user
* @return Optional.empty() if the phone number is invalid, else Optional.of(new phone number)
*/
private static Optional<String> getNewPhone(String rawArgs){
final int indexOfPhonePrefix = rawArgs.indexOf(PERSON_DATA_PREFIX_PHONE);
String newPhone;
if (!isEmailChanging(rawArgs)){
newPhone = removePrefixSign(rawArgs.substring(indexOfPhonePrefix).trim(), PERSON_DATA_PREFIX_PHONE);
} else {
final int indexOfEmailPrefix = rawArgs.indexOf(PERSON_DATA_PREFIX_EMAIL);
if (indexOfEmailPrefix < indexOfPhonePrefix){
newPhone = removePrefixSign(rawArgs.substring(indexOfPhonePrefix).trim(), PERSON_DATA_PREFIX_PHONE);
} else {
newPhone = removePrefixSign(rawArgs.substring(indexOfPhonePrefix, indexOfEmailPrefix).trim(), PERSON_DATA_PREFIX_PHONE);
}
}
if (isPersonPhoneValid(newPhone)){
return Optional.of(newPhone);
} else {
return Optional.empty();
}
}

/**
* Checks if the command requires email to be changed
* @param rawArgs full command from the user
* @return whether email is to be changed
*/
private static boolean isEmailChanging(String rawArgs){
final int indexOfEmailPrefix = rawArgs.indexOf(PERSON_DATA_PREFIX_EMAIL);
return indexOfEmailPrefix != -1;
}

/**
* Extracts the new email
* @param rawArgs full command from the user
* @return Optional.empty() if the email is invalid, else optional.of(new email)
*/
private static Optional<String> getNewEmail(String rawArgs){
final int indexOfEmailPrefix = rawArgs.indexOf(PERSON_DATA_PREFIX_EMAIL);
String newEmail;
if (!isPhoneChanging(rawArgs)){
newEmail = removePrefixSign(rawArgs.substring(indexOfEmailPrefix).trim(), PERSON_DATA_PREFIX_EMAIL);
} else {
final int indexOfPhonePrefix = rawArgs.indexOf(PERSON_DATA_PREFIX_PHONE);
if (indexOfEmailPrefix > indexOfPhonePrefix){
newEmail = removePrefixSign(rawArgs.substring(indexOfEmailPrefix).trim(), PERSON_DATA_PREFIX_PHONE);
} else {
newEmail = removePrefixSign(rawArgs.substring(indexOfEmailPrefix, indexOfPhonePrefix).trim(), PERSON_DATA_PREFIX_PHONE);
}
}
if (isPersonEmailValid(newEmail)){
return Optional.of(newEmail);
} else {
return Optional.empty();
}
}

/**
* Get message for a successful update
* @param updatedPerson String[] describing the person after updating
* @return message for a successful update
*/
private static String getMessageForSuccessfulUpdate(String[] updatedPerson) {
return String.format(MESSAGE_UPDATE_PERSON_SUCCESS, getMessageForFormattedPersonData(updatedPerson));
}

/**
* Clears all persons in the address book.
*
Expand Down Expand Up @@ -801,6 +979,22 @@ private static boolean deletePersonFromAddressBook(String[] exactPerson) {
return changed;
}

/**
* Update the specified person from the addressbook if it is inside. Save changes to storage file.
*
* @param exactPerson the actual person inside the address book
* @param index the index of field to update
* @param content the new content to replace the old content
* @return true if the update process is successful
*/
private static boolean updatePersonFromAddressbook(String[] exactPerson, int index, String content){
final boolean deleted = deletePersonFromAddressBook(exactPerson);
if (! deleted){ return false;}
exactPerson[index] = content;
addPersonToAddressBook(exactPerson);
return true;
}

/**
* Returns all persons in the address book
*/
Expand Down Expand Up @@ -1086,6 +1280,7 @@ private static String getUsageInfoForAllCommands() {
+ getUsageInfoForFindCommand() + LS
+ getUsageInfoForViewCommand() + LS
+ getUsageInfoForDeleteCommand() + LS
+ getUsageInfoForUpdateCommand() + LS
+ getUsageInfoForClearCommand() + LS
+ getUsageInfoForExitCommand() + LS
+ getUsageInfoForHelpCommand();
Expand All @@ -1112,6 +1307,13 @@ private static String getUsageInfoForDeleteCommand() {
+ String.format(MESSAGE_COMMAND_HELP_EXAMPLE, COMMAND_DELETE_EXAMPLE) + LS;
}

/** Returns the String for showing 'update' command usage instruction */
private static String getUsageInfoForUpdateCommand() {
return String.format(MESSAGE_COMMAND_HELP, COMMAND_UPDATE_WORD, COMMAND_UPDATE_DESC) + LS
+ String.format(MESSAGE_COMMAND_HELP_PARAMETERS, COMMAND_UPDATE_PARAMETERS) + LS
+ String.format(MESSAGE_COMMAND_HELP_EXAMPLE, COMMAND_UPDATE_EXAMPLE) + LS;
}

/** Returns string for showing 'clear' command usage instruction */
private static String getUsageInfoForClearCommand() {
return String.format(MESSAGE_COMMAND_HELP, COMMAND_CLEAR_WORD, COMMAND_CLEAR_DESC) + LS
Expand Down
4 changes: 4 additions & 0 deletions test/expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
|| Parameters: INDEX
|| Example: delete 1
||
|| update: Update a person's phone number or email address
|| Parameters: INDEX (Optional)p/NEW PHONE NUMBER (Optional)e/NEW EMAIL
|| Example: update1 p/12345678
||
|| clear: Clears address book permanently.
|| Example: clear
||
Expand Down