diff --git a/README.md b/README.md
index f1ca56ee..2a49ff20 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
# AddressBook (Level 1)
-* This is a CLI (Command Line Interface) Address Book application **written in procedural fashion**.
-* It is a Java sample application intended for students learning Software Engineering while using Java as
- the main programming language.
-* It provides a **reasonably well-written** code example that is **significantly bigger** than what students
- usually write in data structure modules.
-* It can be used to achieve a number of beginner-level [learning outcomes](#learning-outcomes) without
+* This is a CLI (Command Line Interface) Address Book application **written in procedural fashion**.
+* It is a Java sample application intended for students learning Software Engineering while using Java as
+ the main programming language.
+* It provides a **reasonably well-written** code example that is **significantly bigger** than what students
+ usually write in data structure modules.
+* It can be used to achieve a number of beginner-level [learning outcomes](#learning-outcomes) without
running into the complications of OOP or GUI programmings.
**Table of Contents**
@@ -35,7 +35,7 @@
-----------------------------------------------------------------------------------------------------
# User Guide
-This product is not meant for end-users and therefore there is no user-friendly installer.
+This product is not meant for end-users and therefore there is no user-friendly installer.
Please refer to the [Setting up](#setting-up) section to learn how to set up the project.
## Starting the program
@@ -59,9 +59,9 @@ Please refer to the [Setting up](#setting-up) section to learn how to set up the
## List of commands
#### Viewing help: `help`
-Format: `help`
+Format: `help`
> Help is also shown if you enter an incorrect command e.g. `abcd`
-
+
#### Adding a person: `add`
> Adds a person to the address book
@@ -69,43 +69,50 @@ Format: `add NAME p/PHONE_NUMBER e/EMAIL`
> Words in `UPPER_CASE` are the parameters
Phone number and email can be in any order but the name must come first.
-Examples:
+Examples:
* `add John Doe p/98765432 e/johnd@gmail.com`
* `add Betsy Crowe e/bencrowe@gmail.com p/1234567 `
#### Listing all persons: `list`
-> Shows a list of persons, as an indexed list, in the order they were added to the address book,
+> Shows a list of persons, as an indexed list, in the order they were added to the address book,
oldest first.
Format: `list`
+#### Sorting all persons by name: `sort`
+
+> Sorts the list of persons by name, and displays persons
+in ascending or descending lexicographical order depending on user input.
+
+Format: `sort [ASC/DESC]`
+
#### Finding a person by keyword `find`
> Finds persons that match given keywords
Format: `find KEYWORD [MORE_KEYWORDS]`
-> The search is case sensitive, the order of the keywords does not matter, only the name is searched,
+> The search is case sensitive, the order of the keywords does not matter, only the name is searched,
and persons matching at least one keyword will be returned (i.e. `OR` search).
-Examples:
+Examples:
* `find John`
> Returns `John Doe` but not `john`
-
+
* `find Betsy Tim John`
> Returns Any person having names `Betsy`, `Tim`, or `John`
#### Deleting a person: `delete`
Format: `delete INDEX`
-> Deletes the person at the specified `INDEX`.
+> Deletes the person at the specified `INDEX`.
The index refers to the index numbers shown in the most recent listing.
-Examples:
+Examples:
* `list`
`delete 2`
> Deletes the 2nd person in the address book.
-
-* `find Betsy`
+
+* `find Betsy`
`delete 1`
> Deletes the 1st person in the results of the `find` command.
@@ -116,8 +123,8 @@ Format: `clear`
#### Exiting the program: `exit`
Format: `exit`
-#### Saving the data
-Address book data are saved in the hard disk automatically after any command that changes the data.
+#### Saving the data
+Address book data are saved in the hard disk automatically after any command that changes the data.
There is no need to save manually.
#### Changing the save location
@@ -144,7 +151,7 @@ Example:
**Prerequisites**
-* JDK 8 or later
+* JDK 8 or later
* IntelliJ IDE
**Importing the project into IntelliJ**
@@ -181,14 +188,14 @@ In-memory data are held in a `ArrayList` where each `String[]` object
1. Open a DOS window in the `test` folder
2. Run the `runtests.bat` script
-3. If the script reports that there is no difference between `actual.txt` and `expected.txt`,
+3. If the script reports that there is no difference between `actual.txt` and `expected.txt`,
the test has passed.
**Mac/Unix/Linux**
1. Open a terminal window in the `test` folder
2. Run the `runtests.sh` script
-3. If the script reports that there is no difference between `actual.txt` and `expected.txt`,
+3. If the script reports that there is no difference between `actual.txt` and `expected.txt`,
the test has passed.
**Troubleshooting test failures**
@@ -211,7 +218,7 @@ corresponding exercises.
* Learn [how to set up a project in IntelliJ](https://se-edu.github.io/se-book/intellij/projectSetup/).
-#### Exercise: Setup project in IntelliJ
+#### Exercise: Setup project in IntelliJ
Part A:
* Create a new project in IntelliJ and write a small HelloWorld program.
@@ -226,10 +233,10 @@ Part B:
## Navigate code efficiently `[LO-CodeNavigation]`
-The `AddressBook.java` code is rather long, which makes it cumbersome to navigate by scrolling alone.
-Navigating code using IDE shortcuts is a more efficient option.
+The `AddressBook.java` code is rather long, which makes it cumbersome to navigate by scrolling alone.
+Navigating code using IDE shortcuts is a more efficient option.
For example, CTRL+B will navigate to the definition of the method/field at the cursor.
-
+
Learn [basic IntelliJ code navigation features](https://se-edu.github.io/se-book/intellij/codeNavigation/).
#### Exercise: Learn to navigate code using shortcuts
@@ -244,7 +251,7 @@ Learn [basic IntelliJ debugging features](https://se-edu.github.io/se-book/intel
Prerequisite: `[LO-IdeSetup]`
-Demonstrate your debugging skills using the AddressBook code.
+Demonstrate your debugging skills using the AddressBook code.
Here are some things you can do in your demonstration:
@@ -262,7 +269,7 @@ Learn [how to automate testing of CLIs](https://se-edu.github.io/se-book/testing
* Run the tests as explained in the [Testing](#testing) section.
* Examine the test script to understand how the script works.
-* Add a few more tests to the `input.txt`. Run the tests. It should fail.
+* Add a few more tests to the `input.txt`. Run the tests. It should fail.
Modify `expected.txt` to make the tests pass again.
* Edit the `AddressBook.java` to modify the behavior slightly and modify tests to match.
@@ -314,7 +321,7 @@ Compare the code with and without the varargs feature.
## Follow a coding standard `[LO-CodingStandard]`
-The given code follows the [coding standard][coding-standard]
+The given code follows the [coding standard][coding-standard]
for the most part.
This learning outcome is covered by the exercise in `[LO-Refactor]`.
@@ -376,12 +383,12 @@ A well-abstracted method should do only one thing.
While it is short, there are some problems with how it has been abstracted.
1. It contains the term `sign` which is not a term used by the AddressBook vocabulary.
-
+
> **A method adds a new term to the vocabulary used to express the solution**.
> Therefore, it is not good when a method name contains terms that are not strictly necessary to express the
> solution (e.g. there is another term already used to express the same thing) or not in tune with the solution
> (e.g. it does not go well with the other terms already used).
-
+
2. Its implementation is not doing exactly what is advertised by the method name and the header comment.
For example, the code does not remove only prefixes; it removes `sign` from anywhere in the `s`.
3. The method can be _more general_ and _more independent_ from the rest of the code. For example,
@@ -394,7 +401,7 @@ While it is short, there are some problems with how it has been abstracted.
*/
private static String removePrefix(String fullString, String prefix) { ... }
```
-
+
If needed, a more AddressBook-specific method that works on parameter strings only can be defined.
In that case, that method can make use of the more general method suggested above.
@@ -432,11 +439,11 @@ readability.
#### Exercise 2: Refactor the code to make it worse!
-Sometimes, going in the wrong direction can be a good learning experience too.
+Sometimes, going in the wrong direction can be a good learning experience too.
In this exercise, we explore how low code qualities can go.
* Refactor the code to make the code as bad as possible.
- i.e. How bad can you make it without breaking the functionality while still making it look like it was written by a
+ i.e. How bad can you make it without breaking the functionality while still making it look like it was written by a
programmer (but a very bad programmer :-)).
* In particular, inlining methods can worsen the code quality fast.
@@ -468,4 +475,4 @@ The full list of contributors for se-edu can be found [here](https://se-edu.gith
* If you would like to contact us, refer to [our website](https://se-edu.github.io/#contact).
[coding-standard]: https://github.com/oss-generic/process/blob/master/codingStandards/CodingStandard-Java.md "Java Coding Standard"
-[code-quality]: https://se-edu.github.io/se-book/codeQuality/ "Code Quality Best Practices"
\ No newline at end of file
+[code-quality]: https://se-edu.github.io/se-book/codeQuality/ "Code Quality Best Practices"
diff --git a/src/seedu/addressbook/AddressBook.java b/src/seedu/addressbook/AddressBook.java
index 5a158b67..9b394b32 100644
--- a/src/seedu/addressbook/AddressBook.java
+++ b/src/seedu/addressbook/AddressBook.java
@@ -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 : =============================================================
@@ -105,6 +98,11 @@ public class AddressBook {
+ PERSON_DATA_PREFIX_EMAIL + "EMAIL";
private static final String COMMAND_ADD_EXAMPLE = COMMAND_ADD_WORD + " John Doe p/98765432 e/johnd@gmail.com";
+ private static final String COMMAND_SORT_WORD = "sort";
+ private static final String COMMAND_SORT_DESC = "Sorts persons list by asc/desc name order";
+ private static final String COMMAND_SORT_PARAMETER = "ASC/DESC";
+ private static final String COMMAND_SORT_EXAMPLE = COMMAND_SORT_WORD + " ASC/DESC";
+
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.";
@@ -141,9 +139,15 @@ public class AddressBook {
* used by the internal String[] storage format.
* For example, a person's name is stored as the 0th element in the array.
*/
- 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;
+
+// private static final String PERSON_PROPERTY_NAME = "name";
+// private static final String PERSON_PROPERTY_EMAIL = "email";
+// private static final String PERSON_PROPERTY_PHONE = "phone";
+
+ // Replaces PERSON_PROPERTY_ with enums variant
+ private enum PersonProperty {
+ NAME, EMAIL, PHONE
+ };
/**
* The number of data elements for a single person.
@@ -181,14 +185,14 @@ public class AddressBook {
/**
* List of all persons in the address book.
*/
- private static final ArrayList ALL_PERSONS = new ArrayList<>();
+ private static final ArrayList> 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 latestPersonListingView = getAllPersonsInAddressBook(); // initial view is of all
+ private static ArrayList> latestPersonListingView = getAllPersonsInAddressBook(); // initial view is of all
/**
* The path to the file used for storing person data.
@@ -369,22 +373,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_SORT_WORD:
+ return executeSortPerson(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());
}
}
@@ -417,7 +423,7 @@ private static String getMessageForInvalidCommandInput(String userCommand, Strin
*/
private static String executeAddPerson(String commandArgs) {
// try decoding a person from the raw args
- final Optional decodeResult = decodePersonFromString(commandArgs);
+ final Optional> decodeResult = decodePersonFromString(commandArgs);
// checks if args are valid (decode result will not be present if the person is invalid)
if (!decodeResult.isPresent()) {
@@ -425,7 +431,7 @@ private static String executeAddPerson(String commandArgs) {
}
// add the person as specified
- final String[] personToAdd = decodeResult.get();
+ final HashMap personToAdd = decodeResult.get();
addPersonToAddressBook(personToAdd);
return getMessageForSuccessfulAddPerson(personToAdd);
}
@@ -437,7 +443,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 addedPerson) {
return String.format(MESSAGE_ADDED,
getNameFromPerson(addedPerson), getPhoneFromPerson(addedPerson), getEmailFromPerson(addedPerson));
}
@@ -451,7 +457,7 @@ private static String getMessageForSuccessfulAddPerson(String[] addedPerson) {
*/
private static String executeFindPersons(String commandArgs) {
final Set keywords = extractKeywordsFromFindPersonArgs(commandArgs);
- final ArrayList personsFound = getPersonsWithNameContainingAnyKeyword(keywords);
+ final ArrayList> personsFound = getPersonsWithNameContainingAnyKeyword(keywords);
showToUser(personsFound);
return getMessageForPersonsDisplayedSummary(personsFound);
}
@@ -462,7 +468,7 @@ private static String executeFindPersons(String commandArgs) {
* @param personsDisplayed used to generate summary
* @return summary message for persons displayed
*/
- private static String getMessageForPersonsDisplayedSummary(ArrayList personsDisplayed) {
+ private static String getMessageForPersonsDisplayedSummary(ArrayList> personsDisplayed) {
return String.format(MESSAGE_PERSONS_FOUND_OVERVIEW, personsDisplayed.size());
}
@@ -482,9 +488,9 @@ private static Set extractKeywordsFromFindPersonArgs(String findPersonCo
* @param keywords for searching
* @return list of persons in full model with name containing some of the keywords
*/
- private static ArrayList getPersonsWithNameContainingAnyKeyword(Collection keywords) {
- final ArrayList matchedPersons = new ArrayList<>();
- for (String[] person : getAllPersonsInAddressBook()) {
+ private static ArrayList> getPersonsWithNameContainingAnyKeyword(Collection keywords) {
+ final ArrayList> matchedPersons = new ArrayList<>();
+ for (HashMap person : getAllPersonsInAddressBook()) {
final Set wordsInName = new HashSet<>(splitByWhitespace(getNameFromPerson(person)));
if (!Collections.disjoint(wordsInName, keywords)) {
matchedPersons.add(person);
@@ -507,11 +513,43 @@ private static String executeDeletePerson(String commandArgs) {
if (!isDisplayIndexValidForLastPersonListingView(targetVisibleIndex)) {
return MESSAGE_INVALID_PERSON_DISPLAYED_INDEX;
}
- final String[] targetInModel = getPersonByLastVisibleIndex(targetVisibleIndex);
+ final HashMap targetInModel = getPersonByLastVisibleIndex(targetVisibleIndex);
return deletePersonFromAddressBook(targetInModel) ? getMessageForSuccessfulDelete(targetInModel) // success
: MESSAGE_PERSON_NOT_IN_ADDRESSBOOK; // not found
}
+ /**
+ * Sorts entries by ascending or descending order by NAME
+ *
+ * @param commandArgs full command args string from the user
+ * @return feedback display message for the operation result
+ */
+ private static String executeSortPerson(String commandArgs) {
+ ArrayList> targetPersonList = ALL_PERSONS;
+
+ ArrayList personNames = new ArrayList ();
+ HashMap> bruteHash = new HashMap> ();
+ for (HashMap person: targetPersonList) {
+ personNames.add(person.get(PersonProperty.NAME));
+ bruteHash.put(person.get(PersonProperty.NAME), person);
+ }
+
+ if (commandArgs.equals("ASC")) {
+ Collections.sort(personNames);
+ } else if (commandArgs.equals("DESC")) {
+ Collections.sort(personNames, Collections.reverseOrder());
+ } else {
+ return getMessageForInvalidCommandInput(COMMAND_SORT_WORD, getUsageInfoForSortCommand());
+ }
+
+ targetPersonList.clear();
+ for (String name: personNames) {
+ addPersonToAddressBook(bruteHash.get(name));
+ }
+
+ return getMessageForPersonsDisplayedSummary(targetPersonList);
+ }
+
/**
* Checks validity of delete person argument string's format.
*
@@ -554,7 +592,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 deletedPerson) {
return String.format(MESSAGE_DELETE_PERSON_SUCCESS, getMessageForFormattedPersonData(deletedPerson));
}
@@ -574,7 +612,7 @@ private static String executeClearAddressBook() {
* @return feedback display message for the operation result
*/
private static String executeListAllPersonsInAddressBook() {
- ArrayList toBeDisplayed = getAllPersonsInAddressBook();
+ ArrayList> toBeDisplayed = getAllPersonsInAddressBook();
showToUser(toBeDisplayed);
return getMessageForPersonsDisplayedSummary(toBeDisplayed);
}
@@ -624,12 +662,24 @@ private static void showToUser(String... message) {
}
}
+ /*
+ private static void showToUser(String[] message) {
+ for (String m : message) {
+ System.out.println(LINE_PREFIX + m);
+ }
+ }
+
+ private static void showToUser(String message) {
+ System.out.println(LINE_PREFIX + message);
+ }
+ */
+
/**
* Shows the list of persons to the user.
* The list will be indexed, starting from 1.
*
*/
- private static void showToUser(ArrayList persons) {
+ private static void showToUser(ArrayList> persons) {
String listAsString = getDisplayString(persons);
showToUser(listAsString);
updateLatestViewedPersonListing(persons);
@@ -638,10 +688,10 @@ private static void showToUser(ArrayList persons) {
/**
* Returns the display string representation of the list of persons.
*/
- private static String getDisplayString(ArrayList persons) {
+ private static String getDisplayString(ArrayList> persons) {
final StringBuilder messageAccumulator = new StringBuilder();
for (int i = 0; i < persons.size(); i++) {
- final String[] person = persons.get(i);
+ final HashMap person = persons.get(i);
final int displayIndex = i + DISPLAYED_INDEX_OFFSET;
messageAccumulator.append('\t')
.append(getIndexedPersonListElementMessage(displayIndex, person))
@@ -657,7 +707,7 @@ private static String getDisplayString(ArrayList 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 person) {
return String.format(MESSAGE_DISPLAY_LIST_ELEMENT_INDEX, visibleIndex) + getMessageForFormattedPersonData(person);
}
@@ -667,7 +717,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 person) {
return String.format(MESSAGE_DISPLAY_PERSON_DATA,
getNameFromPerson(person), getPhoneFromPerson(person), getEmailFromPerson(person));
}
@@ -677,7 +727,7 @@ private static String getMessageForFormattedPersonData(String[] person) {
*
* @param newListing the new listing of persons
*/
- private static void updateLatestViewedPersonListing(ArrayList newListing) {
+ private static void updateLatestViewedPersonListing(ArrayList> newListing) {
// clone to insulate from future changes to arg list
latestPersonListingView = new ArrayList<>(newListing);
}
@@ -688,7 +738,7 @@ private static void updateLatestViewedPersonListing(ArrayList 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 getPersonByLastVisibleIndex(int lastVisibleIndex) {
return latestPersonListingView.get(lastVisibleIndex - DISPLAYED_INDEX_OFFSET);
}
@@ -728,8 +778,8 @@ private static void createFileIfMissing(String filePath) {
* @param filePath file to load from
* @return the list of decoded persons
*/
- private static ArrayList loadPersonsFromFile(String filePath) {
- final Optional> successfullyDecoded = decodePersonsFromStrings(getLinesInFile(filePath));
+ private static ArrayList> loadPersonsFromFile(String filePath) {
+ final Optional>> successfullyDecoded = decodePersonsFromStrings(getLinesInFile(filePath));
if (!successfullyDecoded.isPresent()) {
showToUser(MESSAGE_INVALID_STORAGE_FILE_CONTENT);
exitProgram();
@@ -760,7 +810,7 @@ private static ArrayList getLinesInFile(String filePath) {
*
* @param filePath file for saving
*/
- private static void savePersonsToFile(ArrayList persons, String filePath) {
+ private static void savePersonsToFile(ArrayList> persons, String filePath) {
final ArrayList linesToWrite = encodePersonsToStrings(persons);
try {
Files.write(Paths.get(storageFilePath), linesToWrite);
@@ -782,7 +832,7 @@ private static void savePersonsToFile(ArrayList persons, String filePa
*
* @param person to add
*/
- private static void addPersonToAddressBook(String[] person) {
+ private static void addPersonToAddressBook(HashMap person) {
ALL_PERSONS.add(person);
savePersonsToFile(getAllPersonsInAddressBook(), storageFilePath);
}
@@ -793,7 +843,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 exactPerson) {
final boolean changed = ALL_PERSONS.remove(exactPerson);
if (changed) {
savePersonsToFile(getAllPersonsInAddressBook(), storageFilePath);
@@ -804,7 +854,7 @@ private static boolean deletePersonFromAddressBook(String[] exactPerson) {
/**
* Returns all persons in the address book
*/
- private static ArrayList getAllPersonsInAddressBook() {
+ private static ArrayList> getAllPersonsInAddressBook() {
return ALL_PERSONS;
}
@@ -821,7 +871,7 @@ private static void clearAddressBook() {
*
* @param persons list of persons to initialise the model with
*/
- private static void initialiseAddressBookModel(ArrayList persons) {
+ private static void initialiseAddressBookModel(ArrayList> persons) {
ALL_PERSONS.clear();
ALL_PERSONS.addAll(persons);
}
@@ -838,8 +888,8 @@ private static void initialiseAddressBookModel(ArrayList persons) {
*
* @param person whose name you want
*/
- private static String getNameFromPerson(String[] person) {
- return person[PERSON_DATA_INDEX_NAME];
+ private static String getNameFromPerson(HashMap person) {
+ return person.get(PersonProperty.NAME);
}
/**
@@ -847,8 +897,8 @@ private static String getNameFromPerson(String[] person) {
*
* @param person whose phone number you want
*/
- private static String getPhoneFromPerson(String[] person) {
- return person[PERSON_DATA_INDEX_PHONE];
+ private static String getPhoneFromPerson(HashMap person) {
+ return person.get(PersonProperty.PHONE);
}
/**
@@ -856,8 +906,8 @@ private static String getPhoneFromPerson(String[] person) {
*
* @param person whose email you want
*/
- private static String getEmailFromPerson(String[] person) {
- return person[PERSON_DATA_INDEX_EMAIL];
+ private static String getEmailFromPerson(HashMap person) {
+ return person.get(PersonProperty.EMAIL);
}
/**
@@ -868,11 +918,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 makePersonFromData(String name, String phone, String email) {
+ final HashMap person = new HashMap ();
+ person.put(PersonProperty.NAME, name);
+ person.put(PersonProperty.EMAIL, email);
+ person.put(PersonProperty.PHONE, phone);
return person;
}
@@ -882,7 +932,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 person) {
return String.format(PERSON_STRING_REPRESENTATION,
getNameFromPerson(person), getPhoneFromPerson(person), getEmailFromPerson(person));
}
@@ -893,9 +943,9 @@ private static String encodePersonToString(String[] person) {
* @param persons to be encoded
* @return encoded strings
*/
- private static ArrayList encodePersonsToStrings(ArrayList persons) {
+ private static ArrayList encodePersonsToStrings(ArrayList> persons) {
final ArrayList encoded = new ArrayList<>();
- for (String[] person : persons) {
+ for (HashMap person : persons) {
encoded.add(encodePersonToString(person));
}
return encoded;
@@ -915,18 +965,18 @@ private static ArrayList encodePersonsToStrings(ArrayList pers
* @return if cannot decode: empty Optional
* else: Optional containing decoded person
*/
- private static Optional decodePersonFromString(String encoded) {
+ private static Optional> decodePersonFromString(String encoded) {
// check that we can extract the parts of a person from the encoded string
- if (!isPersonDataExtractableFrom(encoded)) {
- return Optional.empty();
+ if (isPersonDataExtractableFrom(encoded)) {
+ final HashMap decodedPerson = makePersonFromData(
+ extractNameFromPersonString(encoded),
+ extractPhoneFromPersonString(encoded),
+ extractEmailFromPersonString(encoded)
+ );
+ // check that the constructed person is valid
+ return isPersonDataValid(decodedPerson) ? Optional.of(decodedPerson) : Optional.empty();
}
- final String[] decodedPerson = makePersonFromData(
- extractNameFromPersonString(encoded),
- extractPhoneFromPersonString(encoded),
- extractEmailFromPersonString(encoded)
- );
- // check that the constructed person is valid
- return isPersonDataValid(decodedPerson) ? Optional.of(decodedPerson) : Optional.empty();
+ return Optional.empty();
}
/**
@@ -936,10 +986,10 @@ private static Optional decodePersonFromString(String encoded) {
* @return if cannot decode any: empty Optional
* else: Optional containing decoded persons
*/
- private static Optional> decodePersonsFromStrings(ArrayList encodedPersons) {
- final ArrayList decodedPersons = new ArrayList<>();
+ private static Optional>> decodePersonsFromStrings(ArrayList encodedPersons) {
+ final ArrayList> decodedPersons = new ArrayList<>();
for (String encodedPerson : encodedPersons) {
- final Optional decodedPerson = decodePersonFromString(encodedPerson);
+ final Optional> decodedPerson = decodePersonFromString(encodedPerson);
if (!decodedPerson.isPresent()) {
return Optional.empty();
}
@@ -957,10 +1007,12 @@ private static Optional> decodePersonsFromStrings(ArrayList<
private static boolean isPersonDataExtractableFrom(String personData) {
final String matchAnyPersonDataPrefix = PERSON_DATA_PREFIX_PHONE + '|' + PERSON_DATA_PREFIX_EMAIL;
final String[] splitArgs = personData.trim().split(matchAnyPersonDataPrefix);
- return splitArgs.length == 3 // 3 arguments
- && !splitArgs[0].isEmpty() // non-empty arguments
- && !splitArgs[1].isEmpty()
- && !splitArgs[2].isEmpty();
+ for (String arg: splitArgs) {
+ if (arg.isEmpty()) {
+ return false;
+ }
+ }
+ return splitArgs.length == PERSON_DATA_COUNT;
}
/**
@@ -1028,10 +1080,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 person) {
+ return isPersonNameValid(person.get(PersonProperty.NAME))
+ && isPersonPhoneValid(person.get(PersonProperty.PHONE))
+ && isPersonEmailValid(person.get(PersonProperty.EMAIL));
}
/*
@@ -1083,6 +1135,7 @@ private static boolean isPersonEmailValid(String email) {
/** Returns usage info for all commands */
private static String getUsageInfoForAllCommands() {
return getUsageInfoForAddCommand() + LS
+ + getUsageInfoForSortCommand() + LS
+ getUsageInfoForFindCommand() + LS
+ getUsageInfoForViewCommand() + LS
+ getUsageInfoForDeleteCommand() + LS
@@ -1098,6 +1151,13 @@ private static String getUsageInfoForAddCommand() {
+ String.format(MESSAGE_COMMAND_HELP_EXAMPLE, COMMAND_ADD_EXAMPLE) + LS;
}
+ /** Returns the string for showing 'sort' command usage instruction */
+ private static String getUsageInfoForSortCommand() {
+ return String.format(MESSAGE_COMMAND_HELP, COMMAND_SORT_WORD, COMMAND_SORT_DESC) + LS
+ + String.format(MESSAGE_COMMAND_HELP_PARAMETERS, COMMAND_SORT_PARAMETER) + LS
+ + String.format(MESSAGE_COMMAND_HELP_EXAMPLE, COMMAND_SORT_EXAMPLE) + LS;
+ }
+
/** Returns the string for showing 'find' command usage instruction */
private static String getUsageInfoForFindCommand() {
return String.format(MESSAGE_COMMAND_HELP, COMMAND_FIND_WORD, COMMAND_FIND_DESC) + LS