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

[W4.6b][F12-A2]Liu Yiming #33

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
119 changes: 57 additions & 62 deletions src/seedu/addressbook/AddressBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Optional;
import java.util.Scanner;
import java.util.Set;
import java.util.HashMap;

/*
* NOTE : =============================================================
Expand Down Expand Up @@ -136,19 +137,12 @@ public class AddressBook {
private static final String DIVIDER = "===================================================";


/* We use a String array to store details of a single person.
* The constants given below are the indexes for the different data elements of a person
* used by the internal String[] storage format.
* For example, a person's name is stored as the 0th element in the array.
/* We use a HashMap to store details of a single person.
* The enum variable given below are the keys for the different data elements of a person
* used by the internal HashMap<PersonalProperty,String> storage format.
* For example, a person's name is stored as the "PersonaProperty.NAME" element in the HashMap.
*/
private static final int PERSON_DATA_INDEX_NAME = 0;
private static final int PERSON_DATA_INDEX_PHONE = 1;
private static final int PERSON_DATA_INDEX_EMAIL = 2;

/**
* The number of data elements for a single person.
*/
private static final int PERSON_DATA_COUNT = 3;
private enum PersonProperty {NAME, EMAIL, PHONE};

/**
* Offset required to convert between 1-indexing and 0-indexing.COMMAND_
Expand Down Expand Up @@ -181,14 +175,15 @@ public class AddressBook {
/**
* List of all persons in the address book.
*/
private static final ArrayList<String[]> ALL_PERSONS = new ArrayList<>();
private static final ArrayList<HashMap<PersonProperty,String>> ALL_PERSONS = new ArrayList<>();

/**
* Stores the most recent list of persons shown to the user as a result of a user command.
* This is a subset of the full list. Deleting persons in the pull list does not delete
* those persons from this list.
*/
private static ArrayList<String[]> latestPersonListingView = getAllPersonsInAddressBook(); // initial view is of all
private static ArrayList<HashMap<PersonProperty,String>> latestPersonListingView = getAllPersonsInAddressBook();
// initial view is of all

/**
* The path to the file used for storing person data.
Expand Down Expand Up @@ -417,15 +412,15 @@ private static String getMessageForInvalidCommandInput(String userCommand, Strin
*/
private static String executeAddPerson(String commandArgs) {
// try decoding a person from the raw args
final Optional<String[]> decodeResult = decodePersonFromString(commandArgs);
final Optional<HashMap<PersonProperty,String>> decodeResult = decodePersonFromString(commandArgs);

// checks if args are valid (decode result will not be present if the person is invalid)
if (!decodeResult.isPresent()) {
return getMessageForInvalidCommandInput(COMMAND_ADD_WORD, getUsageInfoForAddCommand());
}

// add the person as specified
final String[] personToAdd = decodeResult.get();
final HashMap<PersonProperty,String> personToAdd = decodeResult.get();
addPersonToAddressBook(personToAdd);
return getMessageForSuccessfulAddPerson(personToAdd);
}
Expand All @@ -437,7 +432,7 @@ private static String executeAddPerson(String commandArgs) {
* @param addedPerson person who was successfully added
* @return successful add person feedback message
*/
private static String getMessageForSuccessfulAddPerson(String[] addedPerson) {
private static String getMessageForSuccessfulAddPerson(HashMap<PersonProperty,String> addedPerson) {
return String.format(MESSAGE_ADDED,
getNameFromPerson(addedPerson), getPhoneFromPerson(addedPerson), getEmailFromPerson(addedPerson));
}
Expand All @@ -451,7 +446,7 @@ private static String getMessageForSuccessfulAddPerson(String[] addedPerson) {
*/
private static String executeFindPersons(String commandArgs) {
final Set<String> keywords = extractKeywordsFromFindPersonArgs(commandArgs);
final ArrayList<String[]> personsFound = getPersonsWithNameContainingAnyKeyword(keywords);
final ArrayList<HashMap<PersonProperty,String>> personsFound = getPersonsWithNameContainingAnyKeyword(keywords);
showToUser(personsFound);
return getMessageForPersonsDisplayedSummary(personsFound);
}
Expand All @@ -462,7 +457,7 @@ private static String executeFindPersons(String commandArgs) {
* @param personsDisplayed used to generate summary
* @return summary message for persons displayed
*/
private static String getMessageForPersonsDisplayedSummary(ArrayList<String[]> personsDisplayed) {
private static String getMessageForPersonsDisplayedSummary(ArrayList<HashMap<PersonProperty,String>> personsDisplayed) {
return String.format(MESSAGE_PERSONS_FOUND_OVERVIEW, personsDisplayed.size());
}

Expand All @@ -482,9 +477,9 @@ private static Set<String> extractKeywordsFromFindPersonArgs(String findPersonCo
* @param keywords for searching
* @return list of persons in full model with name containing some of the keywords
*/
private static ArrayList<String[]> getPersonsWithNameContainingAnyKeyword(Collection<String> keywords) {
final ArrayList<String[]> matchedPersons = new ArrayList<>();
for (String[] person : getAllPersonsInAddressBook()) {
private static ArrayList<HashMap<PersonProperty,String>> getPersonsWithNameContainingAnyKeyword(Collection<String> keywords) {
final ArrayList<HashMap<PersonProperty,String>> matchedPersons = new ArrayList<>();
for (HashMap<PersonProperty,String> person : getAllPersonsInAddressBook()) {
final Set<String> wordsInName = new HashSet<>(splitByWhitespace(getNameFromPerson(person)));
if (!Collections.disjoint(wordsInName, keywords)) {
matchedPersons.add(person);
Expand All @@ -507,7 +502,7 @@ private static String executeDeletePerson(String commandArgs) {
if (!isDisplayIndexValidForLastPersonListingView(targetVisibleIndex)) {
return MESSAGE_INVALID_PERSON_DISPLAYED_INDEX;
}
final String[] targetInModel = getPersonByLastVisibleIndex(targetVisibleIndex);
final HashMap<PersonProperty,String> targetInModel = getPersonByLastVisibleIndex(targetVisibleIndex);
return deletePersonFromAddressBook(targetInModel) ? getMessageForSuccessfulDelete(targetInModel) // success
: MESSAGE_PERSON_NOT_IN_ADDRESSBOOK; // not found
}
Expand Down Expand Up @@ -554,7 +549,7 @@ private static boolean isDisplayIndexValidForLastPersonListingView(int index) {
* @param deletedPerson successfully deleted
* @return successful delete person feedback message
*/
private static String getMessageForSuccessfulDelete(String[] deletedPerson) {
private static String getMessageForSuccessfulDelete(HashMap<PersonProperty,String> deletedPerson) {
return String.format(MESSAGE_DELETE_PERSON_SUCCESS, getMessageForFormattedPersonData(deletedPerson));
}

Expand All @@ -574,7 +569,7 @@ private static String executeClearAddressBook() {
* @return feedback display message for the operation result
*/
private static String executeListAllPersonsInAddressBook() {
ArrayList<String[]> toBeDisplayed = getAllPersonsInAddressBook();
ArrayList<HashMap<PersonProperty,String>> toBeDisplayed = getAllPersonsInAddressBook();
showToUser(toBeDisplayed);
return getMessageForPersonsDisplayedSummary(toBeDisplayed);
}
Expand Down Expand Up @@ -629,7 +624,7 @@ private static void showToUser(String... message) {
* The list will be indexed, starting from 1.
*
*/
private static void showToUser(ArrayList<String[]> persons) {
private static void showToUser(ArrayList<HashMap<PersonProperty,String>> persons) {
String listAsString = getDisplayString(persons);
showToUser(listAsString);
updateLatestViewedPersonListing(persons);
Expand All @@ -638,10 +633,10 @@ private static void showToUser(ArrayList<String[]> persons) {
/**
* Returns the display string representation of the list of persons.
*/
private static String getDisplayString(ArrayList<String[]> persons) {
private static String getDisplayString(ArrayList<HashMap<PersonProperty,String>> persons) {
final StringBuilder messageAccumulator = new StringBuilder();
for (int i = 0; i < persons.size(); i++) {
final String[] person = persons.get(i);
final HashMap<PersonProperty,String> person = persons.get(i);
final int displayIndex = i + DISPLAYED_INDEX_OFFSET;
messageAccumulator.append('\t')
.append(getIndexedPersonListElementMessage(displayIndex, person))
Expand All @@ -657,7 +652,7 @@ private static String getDisplayString(ArrayList<String[]> persons) {
* @param person to show
* @return formatted listing message with index
*/
private static String getIndexedPersonListElementMessage(int visibleIndex, String[] person) {
private static String getIndexedPersonListElementMessage(int visibleIndex, HashMap<PersonProperty,String> person) {
return String.format(MESSAGE_DISPLAY_LIST_ELEMENT_INDEX, visibleIndex) + getMessageForFormattedPersonData(person);
}

Expand All @@ -667,7 +662,7 @@ private static String getIndexedPersonListElementMessage(int visibleIndex, Strin
* @param person to show
* @return formatted message showing internal state
*/
private static String getMessageForFormattedPersonData(String[] person) {
private static String getMessageForFormattedPersonData(HashMap<PersonProperty,String> person) {
return String.format(MESSAGE_DISPLAY_PERSON_DATA,
getNameFromPerson(person), getPhoneFromPerson(person), getEmailFromPerson(person));
}
Expand All @@ -677,7 +672,7 @@ private static String getMessageForFormattedPersonData(String[] person) {
*
* @param newListing the new listing of persons
*/
private static void updateLatestViewedPersonListing(ArrayList<String[]> newListing) {
private static void updateLatestViewedPersonListing(ArrayList<HashMap<PersonProperty,String>> newListing) {
// clone to insulate from future changes to arg list
latestPersonListingView = new ArrayList<>(newListing);
}
Expand All @@ -688,7 +683,7 @@ private static void updateLatestViewedPersonListing(ArrayList<String[]> newListi
* @param lastVisibleIndex displayed index from last shown person listing
* @return the actual person object in the last shown person listing
*/
private static String[] getPersonByLastVisibleIndex(int lastVisibleIndex) {
private static HashMap<PersonProperty,String> getPersonByLastVisibleIndex(int lastVisibleIndex) {
return latestPersonListingView.get(lastVisibleIndex - DISPLAYED_INDEX_OFFSET);
}

Expand Down Expand Up @@ -728,8 +723,8 @@ private static void createFileIfMissing(String filePath) {
* @param filePath file to load from
* @return the list of decoded persons
*/
private static ArrayList<String[]> loadPersonsFromFile(String filePath) {
final Optional<ArrayList<String[]>> successfullyDecoded = decodePersonsFromStrings(getLinesInFile(filePath));
private static ArrayList<HashMap<PersonProperty,String>> loadPersonsFromFile(String filePath) {
final Optional<ArrayList<HashMap<PersonProperty,String>>> successfullyDecoded = decodePersonsFromStrings(getLinesInFile(filePath));
if (!successfullyDecoded.isPresent()) {
showToUser(MESSAGE_INVALID_STORAGE_FILE_CONTENT);
exitProgram();
Expand Down Expand Up @@ -760,7 +755,7 @@ private static ArrayList<String> getLinesInFile(String filePath) {
*
* @param filePath file for saving
*/
private static void savePersonsToFile(ArrayList<String[]> persons, String filePath) {
private static void savePersonsToFile(ArrayList<HashMap<PersonProperty,String>> persons, String filePath) {
final ArrayList<String> linesToWrite = encodePersonsToStrings(persons);
try {
Files.write(Paths.get(storageFilePath), linesToWrite);
Expand All @@ -782,7 +777,7 @@ private static void savePersonsToFile(ArrayList<String[]> persons, String filePa
*
* @param person to add
*/
private static void addPersonToAddressBook(String[] person) {
private static void addPersonToAddressBook(HashMap<PersonProperty,String> person) {
ALL_PERSONS.add(person);
savePersonsToFile(getAllPersonsInAddressBook(), storageFilePath);
}
Expand All @@ -793,7 +788,7 @@ private static void addPersonToAddressBook(String[] person) {
* @param exactPerson the actual person inside the address book (exactPerson == the person to delete in the full list)
* @return true if the given person was found and deleted in the model
*/
private static boolean deletePersonFromAddressBook(String[] exactPerson) {
private static boolean deletePersonFromAddressBook(HashMap<PersonProperty,String> exactPerson) {
final boolean changed = ALL_PERSONS.remove(exactPerson);
if (changed) {
savePersonsToFile(getAllPersonsInAddressBook(), storageFilePath);
Expand All @@ -804,7 +799,7 @@ private static boolean deletePersonFromAddressBook(String[] exactPerson) {
/**
* Returns all persons in the address book
*/
private static ArrayList<String[]> getAllPersonsInAddressBook() {
private static ArrayList<HashMap<PersonProperty,String>> getAllPersonsInAddressBook() {
return ALL_PERSONS;
}

Expand All @@ -821,7 +816,7 @@ private static void clearAddressBook() {
*
* @param persons list of persons to initialise the model with
*/
private static void initialiseAddressBookModel(ArrayList<String[]> persons) {
private static void initialiseAddressBookModel(ArrayList<HashMap<PersonProperty,String>> persons) {
ALL_PERSONS.clear();
ALL_PERSONS.addAll(persons);
}
Expand All @@ -838,26 +833,26 @@ private static void initialiseAddressBookModel(ArrayList<String[]> persons) {
*
* @param person whose name you want
*/
private static String getNameFromPerson(String[] person) {
return person[PERSON_DATA_INDEX_NAME];
private static String getNameFromPerson(HashMap<PersonProperty,String> person) {
return person.get(PersonProperty.NAME);
}

/**
* Returns given person's phone number
*
* @param person whose phone number you want
*/
private static String getPhoneFromPerson(String[] person) {
return person[PERSON_DATA_INDEX_PHONE];
private static String getPhoneFromPerson(HashMap<PersonProperty,String> person) {
return person.get(PersonProperty.PHONE);
}

/**
* Returns given person's email
*
* @param person whose email you want
*/
private static String getEmailFromPerson(String[] person) {
return person[PERSON_DATA_INDEX_EMAIL];
private static String getEmailFromPerson(HashMap<PersonProperty,String> person) {
return person.get(PersonProperty.EMAIL);
}

/**
Expand All @@ -868,11 +863,11 @@ private static String getEmailFromPerson(String[] person) {
* @param email without data prefix
* @return constructed person
*/
private static String[] makePersonFromData(String name, String phone, String email) {
final String[] person = new String[PERSON_DATA_COUNT];
person[PERSON_DATA_INDEX_NAME] = name;
person[PERSON_DATA_INDEX_PHONE] = phone;
person[PERSON_DATA_INDEX_EMAIL] = email;
private static HashMap<PersonProperty,String> makePersonFromData(String name, String phone, String email) {
final HashMap<PersonProperty,String> person = new HashMap<PersonProperty,String>();
person.put(PersonProperty.NAME, name);
person.put(PersonProperty.PHONE, phone);
person.put(PersonProperty.EMAIL, email);
return person;
}

Expand All @@ -882,7 +877,7 @@ private static String[] makePersonFromData(String name, String phone, String ema
* @param person to be encoded
* @return encoded string
*/
private static String encodePersonToString(String[] person) {
private static String encodePersonToString(HashMap<PersonProperty,String> person) {
return String.format(PERSON_STRING_REPRESENTATION,
getNameFromPerson(person), getPhoneFromPerson(person), getEmailFromPerson(person));
}
Expand All @@ -893,9 +888,9 @@ private static String encodePersonToString(String[] person) {
* @param persons to be encoded
* @return encoded strings
*/
private static ArrayList<String> encodePersonsToStrings(ArrayList<String[]> persons) {
private static ArrayList<String> encodePersonsToStrings(ArrayList<HashMap<PersonProperty,String>> persons) {
final ArrayList<String> encoded = new ArrayList<>();
for (String[] person : persons) {
for (HashMap<PersonProperty,String> person : persons) {
encoded.add(encodePersonToString(person));
}
return encoded;
Expand All @@ -915,12 +910,12 @@ private static ArrayList<String> encodePersonsToStrings(ArrayList<String[]> pers
* @return if cannot decode: empty Optional
* else: Optional containing decoded person
*/
private static Optional<String[]> decodePersonFromString(String encoded) {
private static Optional<HashMap<PersonProperty,String>> decodePersonFromString(String encoded) {
// check that we can extract the parts of a person from the encoded string
if (!isPersonDataExtractableFrom(encoded)) {
return Optional.empty();
}
final String[] decodedPerson = makePersonFromData(
final HashMap<PersonProperty,String> decodedPerson = makePersonFromData(
extractNameFromPersonString(encoded),
extractPhoneFromPersonString(encoded),
extractEmailFromPersonString(encoded)
Expand All @@ -936,10 +931,10 @@ private static Optional<String[]> decodePersonFromString(String encoded) {
* @return if cannot decode any: empty Optional
* else: Optional containing decoded persons
*/
private static Optional<ArrayList<String[]>> decodePersonsFromStrings(ArrayList<String> encodedPersons) {
final ArrayList<String[]> decodedPersons = new ArrayList<>();
private static Optional<ArrayList<HashMap<PersonProperty,String>>> decodePersonsFromStrings(ArrayList<String> encodedPersons) {
final ArrayList<HashMap<PersonProperty,String>> decodedPersons = new ArrayList<>();
for (String encodedPerson : encodedPersons) {
final Optional<String[]> decodedPerson = decodePersonFromString(encodedPerson);
final Optional<HashMap<PersonProperty,String>> decodedPerson = decodePersonFromString(encodedPerson);
if (!decodedPerson.isPresent()) {
return Optional.empty();
}
Expand Down Expand Up @@ -1028,10 +1023,10 @@ private static String extractEmailFromPersonString(String encoded) {
*
* @param person String array representing the person (used in internal data)
*/
private static boolean isPersonDataValid(String[] person) {
return isPersonNameValid(person[PERSON_DATA_INDEX_NAME])
&& isPersonPhoneValid(person[PERSON_DATA_INDEX_PHONE])
&& isPersonEmailValid(person[PERSON_DATA_INDEX_EMAIL]);
private static boolean isPersonDataValid(HashMap<PersonProperty,String> person) {
return isPersonNameValid(person.get(PersonProperty.NAME))
&& isPersonPhoneValid(person.get(PersonProperty.PHONE))
&& isPersonEmailValid(person.get(PersonProperty.EMAIL));
}

/*
Expand Down