diff --git a/README.md b/README.md
index f1ca56ee..e78baed6 100644
--- a/README.md
+++ b/README.md
@@ -65,13 +65,13 @@ Format: `help`
#### Adding a person: `add`
> Adds a person to the address book
-Format: `add NAME p/PHONE_NUMBER e/EMAIL`
+Format: `add NAME p/PHONE_NUMBER e/EMAIL c/POSTAL_CODE`
> Words in `UPPER_CASE` are the parameters
Phone number and email can be in any order but the name must come first.
Examples:
-* `add John Doe p/98765432 e/johnd@gmail.com`
-* `add Betsy Crowe e/bencrowe@gmail.com p/1234567 `
+* `add John Doe p/98765432 e/johnd@gmail.com c/123456`
+* `add Betsy Crowe e/bencrowe@gmail.com p/1234567 c/111111`
#### Listing all persons: `list`
diff --git a/src/seedu/addressbook/AddressBook.java b/src/seedu/addressbook/AddressBook.java
index 5a158b67..c904bdfd 100644
--- a/src/seedu/addressbook/AddressBook.java
+++ b/src/seedu/addressbook/AddressBook.java
@@ -65,13 +65,13 @@ public class AddressBook {
* at which java String.format(...) method can insert values.
* =========================================================================
*/
- private static final String MESSAGE_ADDED = "New person added: %1$s, Phone: %2$s, Email: %3$s";
+ private static final String MESSAGE_ADDED = "New person added: %1$s, Phone: %2$s, Email: %3$s, Postal Code: %4$s";
private static final String MESSAGE_ADDRESSBOOK_CLEARED = "Address book has been cleared!";
private static final String MESSAGE_COMMAND_HELP = "%1$s: %2$s";
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_DISPLAY_PERSON_DATA = "%1$s Phone Number: %2$s Email: %3$s";
+ private static final String MESSAGE_DISPLAY_PERSON_DATA = "%1$s Phone Number: %2$s Email: %3$s Postal Code: %4$s";
private static final String MESSAGE_DISPLAY_LIST_ELEMENT_INDEX = "%1$d. ";
private static final String MESSAGE_GOODBYE = "Exiting Address Book... Good bye!";
private static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format: %1$s " + LS + "%2$s";
@@ -94,16 +94,21 @@ public class AddressBook {
// These are the prefix strings to define the data type of a command parameter
private static final String PERSON_DATA_PREFIX_PHONE = "p/";
private static final String PERSON_DATA_PREFIX_EMAIL = "e/";
+ private static final String PERSON_DATA_PREFIX_POSTALCODE = "c/";
private static final String PERSON_STRING_REPRESENTATION = "%1$s " // name
+ PERSON_DATA_PREFIX_PHONE + "%2$s " // phone
- + PERSON_DATA_PREFIX_EMAIL + "%3$s"; // email
+ + PERSON_DATA_PREFIX_EMAIL + "%3$s " // email
+ + PERSON_DATA_PREFIX_POSTALCODE + "%4$s"; // postal code
private static final String COMMAND_ADD_WORD = "add";
private static final String COMMAND_ADD_DESC = "Adds a person to the address book.";
private static final String COMMAND_ADD_PARAMETERS = "NAME "
+ PERSON_DATA_PREFIX_PHONE + "PHONE_NUMBER "
- + PERSON_DATA_PREFIX_EMAIL + "EMAIL";
- private static final String COMMAND_ADD_EXAMPLE = COMMAND_ADD_WORD + " John Doe p/98765432 e/johnd@gmail.com";
+ + PERSON_DATA_PREFIX_EMAIL + "EMAIL "
+ + PERSON_DATA_PREFIX_POSTALCODE + "POSTAL_CODE";
+
+ private static final String COMMAND_ADD_EXAMPLE = COMMAND_ADD_WORD +
+ " John Doe p/98765432 e/johnd@gmail.com c/123456";
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 "
@@ -144,11 +149,13 @@ public class AddressBook {
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 int PERSON_DATA_INDEX_POSTALCODE = 3;
+
/**
* The number of data elements for a single person.
*/
- private static final int PERSON_DATA_COUNT = 3;
+ private static final int PERSON_DATA_COUNT = 4;
/**
* Offset required to convert between 1-indexing and 0-indexing.COMMAND_
@@ -439,7 +446,8 @@ private static String executeAddPerson(String commandArgs) {
*/
private static String getMessageForSuccessfulAddPerson(String[] addedPerson) {
return String.format(MESSAGE_ADDED,
- getNameFromPerson(addedPerson), getPhoneFromPerson(addedPerson), getEmailFromPerson(addedPerson));
+ getNameFromPerson(addedPerson), getPhoneFromPerson(addedPerson),
+ getEmailFromPerson(addedPerson), getPostalFromPerson(addedPerson));
}
/**
@@ -669,7 +677,8 @@ private static String getIndexedPersonListElementMessage(int visibleIndex, Strin
*/
private static String getMessageForFormattedPersonData(String[] person) {
return String.format(MESSAGE_DISPLAY_PERSON_DATA,
- getNameFromPerson(person), getPhoneFromPerson(person), getEmailFromPerson(person));
+ getNameFromPerson(person), getPhoneFromPerson(person),
+ getEmailFromPerson(person), getPostalFromPerson(person));
}
/**
@@ -860,6 +869,15 @@ private static String getEmailFromPerson(String[] person) {
return person[PERSON_DATA_INDEX_EMAIL];
}
+ /**
+ * Returns given person's postal code
+ *
+ * @param person whose postal code you want
+ */
+ private static String getPostalFromPerson(String[] person) {
+ return person[PERSON_DATA_INDEX_POSTALCODE];
+ }
+
/**
* Creates a person from the given data.
*
@@ -868,11 +886,12 @@ private static String getEmailFromPerson(String[] person) {
* @param email without data prefix
* @return constructed person
*/
- private static String[] makePersonFromData(String name, String phone, String email) {
+ private static String[] makePersonFromData(String name, String phone, String email, String postalCode) {
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;
+ person[PERSON_DATA_INDEX_POSTALCODE] = postalCode;
return person;
}
@@ -884,7 +903,8 @@ private static String[] makePersonFromData(String name, String phone, String ema
*/
private static String encodePersonToString(String[] person) {
return String.format(PERSON_STRING_REPRESENTATION,
- getNameFromPerson(person), getPhoneFromPerson(person), getEmailFromPerson(person));
+ getNameFromPerson(person), getPhoneFromPerson(person),
+ getEmailFromPerson(person), getPostalFromPerson(person));
}
/**
@@ -923,7 +943,9 @@ private static Optional decodePersonFromString(String encoded) {
final String[] decodedPerson = makePersonFromData(
extractNameFromPersonString(encoded),
extractPhoneFromPersonString(encoded),
- extractEmailFromPersonString(encoded)
+ extractEmailFromPersonString(encoded),
+ extractPostalFromPersonString(encoded)
+
);
// check that the constructed person is valid
return isPersonDataValid(decodedPerson) ? Optional.of(decodedPerson) : Optional.empty();
@@ -955,12 +977,15 @@ private static Optional> decodePersonsFromStrings(ArrayList<
* @param personData person string representation
*/
private static boolean isPersonDataExtractableFrom(String personData) {
- final String matchAnyPersonDataPrefix = PERSON_DATA_PREFIX_PHONE + '|' + PERSON_DATA_PREFIX_EMAIL;
+ final String matchAnyPersonDataPrefix = PERSON_DATA_PREFIX_PHONE + '|' +
+ PERSON_DATA_PREFIX_EMAIL+ '|' +
+ PERSON_DATA_PREFIX_POSTALCODE;
final String[] splitArgs = personData.trim().split(matchAnyPersonDataPrefix);
- return splitArgs.length == 3 // 3 arguments
+ return splitArgs.length == 4 // 4 arguments
&& !splitArgs[0].isEmpty() // non-empty arguments
&& !splitArgs[1].isEmpty()
- && !splitArgs[2].isEmpty();
+ && !splitArgs[2].isEmpty()
+ && !splitArgs[3].isEmpty();
}
/**
@@ -986,17 +1011,24 @@ private static String extractNameFromPersonString(String encoded) {
private static String extractPhoneFromPersonString(String encoded) {
final int indexOfPhonePrefix = encoded.indexOf(PERSON_DATA_PREFIX_PHONE);
final int indexOfEmailPrefix = encoded.indexOf(PERSON_DATA_PREFIX_EMAIL);
+ final int indexOfPostalPrefix = encoded.indexOf(PERSON_DATA_PREFIX_POSTALCODE);
// phone is last arg, target is from prefix to end of string
- if (indexOfPhonePrefix > indexOfEmailPrefix) {
+ if (indexOfPhonePrefix > indexOfEmailPrefix && indexOfPhonePrefix > indexOfPostalPrefix) {
return removePrefixSign(encoded.substring(indexOfPhonePrefix, encoded.length()).trim(),
PERSON_DATA_PREFIX_PHONE);
- // phone is middle arg, target is from own prefix to next prefix
- } else {
+ // phone is before mail, target is from own prefix to next prefix
+ } else if ((indexOfPhonePrefix < indexOfEmailPrefix && indexOfPostalPrefix < indexOfPhonePrefix)
+ || (indexOfPhonePrefix < indexOfEmailPrefix && indexOfPostalPrefix > indexOfPhonePrefix)) {
return removePrefixSign(
encoded.substring(indexOfPhonePrefix, indexOfEmailPrefix).trim(),
PERSON_DATA_PREFIX_PHONE);
+ // phone is before postal code, target is from own prefix to next prefix
+ } else {
+ return removePrefixSign(
+ encoded.substring(indexOfPhonePrefix, indexOfPostalPrefix).trim(),
+ PERSON_DATA_PREFIX_PHONE);
}
}
@@ -1008,30 +1040,70 @@ private static String extractPhoneFromPersonString(String encoded) {
*/
private static String extractEmailFromPersonString(String encoded) {
final int indexOfPhonePrefix = encoded.indexOf(PERSON_DATA_PREFIX_PHONE);
+ final int indexOfPostalPrefix = encoded.indexOf(PERSON_DATA_PREFIX_POSTALCODE);
final int indexOfEmailPrefix = encoded.indexOf(PERSON_DATA_PREFIX_EMAIL);
// email is last arg, target is from prefix to end of string
- if (indexOfEmailPrefix > indexOfPhonePrefix) {
+ if (indexOfEmailPrefix > indexOfPhonePrefix && indexOfEmailPrefix > indexOfPostalPrefix) {
return removePrefixSign(encoded.substring(indexOfEmailPrefix, encoded.length()).trim(),
PERSON_DATA_PREFIX_EMAIL);
- // email is middle arg, target is from own prefix to next prefix
+ // email is before postal code, target is from own prefix to next prefix
+ } else if ((indexOfEmailPrefix > indexOfPhonePrefix && indexOfEmailPrefix < indexOfPostalPrefix)
+ || (indexOfEmailPrefix < indexOfPhonePrefix && indexOfEmailPrefix < indexOfPostalPrefix)){
+ return removePrefixSign(
+ encoded.substring(indexOfEmailPrefix, indexOfPostalPrefix).trim(),
+ PERSON_DATA_PREFIX_EMAIL);
+ // email is middle arg, phone is last arg, target is from own prefix to next prefix
} else {
return removePrefixSign(
- encoded.substring(indexOfEmailPrefix, indexOfPhonePrefix).trim(),
+ encoded.substring(indexOfPhonePrefix, indexOfEmailPrefix).trim(),
PERSON_DATA_PREFIX_EMAIL);
}
}
+
+ /**
+ * Extracts substring representing postal code from person string representation
+ *
+ * @param encoded person string representation
+ * @return postal code argument WITHOUT prefix
+ */
+ private static String extractPostalFromPersonString(String encoded) {
+ final int indexOfPhonePrefix = encoded.indexOf(PERSON_DATA_PREFIX_PHONE);
+ final int indexOfPostalPrefix = encoded.indexOf(PERSON_DATA_PREFIX_POSTALCODE);
+ final int indexOfEmailPrefix = encoded.indexOf(PERSON_DATA_PREFIX_EMAIL);
+
+ // pc is last arg, target is from prefix to end of string
+ if (indexOfPostalPrefix > indexOfEmailPrefix && indexOfPostalPrefix > indexOfPhonePrefix) {
+ return removePrefixSign(encoded.substring(indexOfPostalPrefix, encoded.length()).trim(),
+ PERSON_DATA_PREFIX_POSTALCODE);
+
+ // pc is before email target is from own prefix to next prefix
+ } else if ((indexOfPostalPrefix < indexOfEmailPrefix && indexOfPhonePrefix < indexOfPostalPrefix)
+ || (indexOfPostalPrefix < indexOfEmailPrefix && indexOfPhonePrefix > indexOfPostalPrefix)){
+ return removePrefixSign(
+ encoded.substring(indexOfPostalPrefix, indexOfEmailPrefix).trim(),
+ PERSON_DATA_PREFIX_POSTALCODE);
+
+ // pc is middle arg, phone is last arg, target is from own prefix to next prefix
+ } else {
+ return removePrefixSign(
+ encoded.substring(indexOfPostalPrefix, indexOfPhonePrefix).trim(),
+ PERSON_DATA_PREFIX_POSTALCODE);
+ }
+ }
+
/**
* Returns true if the given person's data fields are valid
*
* @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]);
+ return isPersonNameValid(person[PERSON_DATA_INDEX_NAME], "(\\w|\\s)+")
+ && isPersonPhoneValid(person[PERSON_DATA_INDEX_PHONE], "\\d+")
+ && isPersonEmailValid(person[PERSON_DATA_INDEX_EMAIL], "\\S+@\\S+\\.\\S+")
+ && isPersonPostalValid(person[PERSON_DATA_INDEX_POSTALCODE], "\\d+");
}
/*
@@ -1046,9 +1118,10 @@ && isPersonPhoneValid(person[PERSON_DATA_INDEX_PHONE])
* Returns true if the given string as a legal person name
*
* @param name to be validated
+ * @param regex
*/
- private static boolean isPersonNameValid(String name) {
- return name.matches("(\\w|\\s)+"); // name is nonempty mixture of alphabets and whitespace
+ private static boolean isPersonNameValid(String name, String regex) {
+ return isPersonPhoneValid(name, regex); // name is nonempty mixture of alphabets and whitespace
//TODO: implement a more permissive validation
}
@@ -1056,9 +1129,10 @@ private static boolean isPersonNameValid(String name) {
* Returns true if the given string as a legal person phone number
*
* @param phone to be validated
+ * @param regex
*/
- private static boolean isPersonPhoneValid(String phone) {
- return phone.matches("\\d+"); // phone nonempty sequence of digits
+ private static boolean isPersonPhoneValid(String phone, String regex) {
+ return phone.matches(regex); // phone nonempty sequence of digits
//TODO: implement a more permissive validation
}
@@ -1066,13 +1140,25 @@ private static boolean isPersonPhoneValid(String phone) {
* Returns true if the given string is a legal person email
*
* @param email to be validated
+ * @param regex
* @return whether arg is a valid person email
*/
- private static boolean isPersonEmailValid(String email) {
- return email.matches("\\S+@\\S+\\.\\S+"); // email is [non-whitespace]@[non-whitespace].[non-whitespace]
+ private static boolean isPersonEmailValid(String email, String regex) {
+ return isPersonPhoneValid(email, regex); // email is [non-whitespace]@[non-whitespace].[non-whitespace]
//TODO: implement a more permissive validation
}
+ /**
+ * Returns true if the given string is a legal postal code
+ *
+ * @param postalCode to be validated
+ * @param regex
+ * @return whether arg is a legal postal code
+ */
+ private static boolean isPersonPostalValid(String postalCode, String regex) {
+ return isPersonPhoneValid(postalCode, regex); // email is [non-whitespace]@[non-whitespace].[non-whitespace]
+ //TODO: implement a more permissive validation
+ }
/*
* ===============================================
diff --git a/test/input.txt b/test/input.txt
index 0b99df54..dcbb227a 100644
--- a/test/input.txt
+++ b/test/input.txt
@@ -19,26 +19,27 @@
# should catch invalid args format
add wrong args wrong args
- add Valid Name p/12345 valid@email.butNoPrefix
- add Valid Name 12345 e/valid@email.butPhonePrefixMissing
+ add Valid Name p/12345 valid@email.butNoPrefix c/111111
+ add Valid Name 12345 e/valid@email.butPhonePrefixMissing c/111111
# should catch invalid person data
add []\[;] p/12345 e/valid@e.mail
- add Valid Name p/not_numbers e/valid@e.mail
- add Valid Name p/12345 e/notAnEmail
+ add Valid Name p/not_numbers e/valid@e.mail c/111111
+ add Valid Name p/12345 e/notAnEmail c/111111
+ add Valid Name p/12345 e/valid@e.mail c/not_numbers
# should add correctly
- add Adam Brown p/111111 e/adam@gmail.com
+ add Adam Brown p/111111 e/adam@gmail.com c/111111
list
- add Betsy Choo p/222222 e/benchoo@nus.edu.sg
+ add Betsy Choo p/222222 e/benchoo@nus.edu.sg c/222222
list
- # order of phone and email should not matter
- add Charlie Dickson e/charlie.d@nus.edu.sg p/333333
+ # order of phone and email and postal code should not matter
+ add Charlie Dickson e/charlie.d@nus.edu.sg p/333333 c/111111
list
- add Dickson Ee e/dickson@nus.edu.sg p/444444
+ add Dickson Ee e/dickson@nus.edu.sg p/444444 c/111111
list
- add Esther Potato p/555555 e/esther@notreal.potato
+ add Esther Potato p/555555 c/111111 e/esther@notreal.potato
list
##########################################################