diff --git a/.travis.yml b/.travis.yml index 89c29645d..6ca4acc56 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,7 @@ matrix: - jdk: oraclejdk9 script: >- - ./gradlew test asciidoctor - + ./gradlew test asciidoctor deploy: skip_cleanup: true provider: script @@ -17,3 +16,6 @@ addons: apt: packages: - oracle-java9-installer +after_success: + - if [ -e ./gradlew ]; then ./gradlew jacocoTestReport;else gradle jacocoTestReport;fi + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/ScreeningHistory.txt b/ScreeningHistory.txt new file mode 100644 index 000000000..35ffd832c --- /dev/null +++ b/ScreeningHistory.txt @@ -0,0 +1,19 @@ +s1234567a 15/10/2018-17:55:01 +s1234567a 15/10/2018-17:55:07 +f1234567a 15/10/2018-17:55:45 +f1234567a 15/10/2018-17:55:55 +s1234567a 15/10/2018-20:03:07 +s1234567a 16/10/2018-11:19:30 +s1234567a 16/10/2018-11:54:56 +s1234567b 16/10/2018-11:58:30 +s1234567b 16/10/2018-11:58:51 +s1234567b 16/10/2018-12:02:34 +s1234567b 16/10/2018-12:04:40 +s1234567b 16/10/2018-12:05:43 +s1234567b 16/10/2018-12:06:18 +s1234567b 16/10/2018-12:07:06 +s1234567b 16/10/2018-12:13:10 +s1234567b 16/10/2018-12:14:24 +s1234567b 16/10/2018-12:16:18 +s1234567b 16/10/2018-12:16:43 +s1234567b 16/10/2018-12:18:34 diff --git a/build.gradle b/build.gradle index 11513b8c8..3ab9d2098 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,7 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { id 'java' id 'org.asciidoctor.convert' version '1.5.6' + id 'jacoco' } sourceCompatibility = JavaVersion.VERSION_1_9 @@ -92,6 +93,13 @@ asciidoctor { } } +jacocoTestReport { + reports { + xml.enabled true + html.enabled false + } +} + // Copies stylesheets into the directory containing generated HTML files as // Asciidoctor does not copy linked CSS files to the output directory when rendering. // This is needed for linked stylesheets and embedded stylesheets which import other files. @@ -101,4 +109,6 @@ task copyStylesheets(type: Copy) { } asciidoctor.dependsOn copyStylesheets +check.dependsOn jacocoTestReport + defaultTasks 'clean', 'test', 'asciidoctor' diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 6817fec1c..4e7be24ea 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -181,22 +181,40 @@ Use case ends. *MSS* +. System prompts user to enter his password +. User enters password +. User keys in NRIC of person to delete +. System deletes the person. + . User requests to list persons. . System shows a list of persons. . User requests to delete a specific person in the list. . System deletes the person. + + Use case ends. *Extensions* -* 2a. The list is empty. +* 2a. The entered password is invalid. +** 2a1. System shows an error message. + +Use case resumes at step 1. + +* 3a. The list is empty. +** 3a1. System shows an error message ++ + Use case ends. -* 3a. The given index is invalid. -** 3a1. System shows an error message. +* 3b. The given NRIC is invalid. +** 3b1. System shows an error message. + +Use case ends. + +* 3c. The person with given NRIC does not exists. +** 3c1. System shows an error message. + Use case resumes at step 3. * *a. At any time, User chooses to cancel the delete action. @@ -242,6 +260,13 @@ Use case ends. *MSS* + +. User requests to find person +. System prompts User to enter his password +. User enters his password +. System prompts User to key in NRIC to find +. User enters NRIC of person + . User requests to find person. . System prompts User to key in NRIC of person. . User enters NRIC of person. @@ -251,6 +276,51 @@ Use case ends. *Extensions* + +* 3a. The entered password is invalid +** 3a1. System shows an error message ++ +Use case resumes in step 2. + +* 5a. The person’s NRIC are entered with invalid format. +** 5a1. System shows an error message. ++ +Use case resumes at step 4. + +* 5b. The list of persons is empty. +** 5b1. System shows an error essage ++ +Use case ends. + +* 6a. Person does not exist in the list +** 6a1. System informs User that person is not in the list ++ +Use case ends. + +* *a. At any time, User chooses to cancel the delete action. +** *a1. System requests confirmation to cancel +** *a2. User confirms the cancellation. ++ +Use case ends + +=== Use case: Check + +*MSS* + +. User requests to check person's screening history +. System prompts User to enter his password +. User enters his password +. System prompts User to key in NRIC to check +. User enters NRIC of person +. System displays past screening timestamps of person, if found on the list. ++ +Use case ends. + +*Extensions* + +* 3a. The entered password is invalid +** 3a1. System shows an error message + * 1a. The list is empty. ** 1a1. System shows an error message. + @@ -258,9 +328,13 @@ Use case ends. * 3a. The person’s details are entered with invalid format. ** 3a1. System shows an error message. + + Use case resumes at step 3. +* 5a. The person’s NRIC are entered with invalid format. +** 5a1. System shows an error message. + * 4a. Person does not exist in the list. ** 4a1. System informs User that person is not in the list. + @@ -279,6 +353,14 @@ Use case ends. *MSS* +* 5b. The list of persons is empty. +** 5b1. System shows an error essage ++ +Use case ends. + +* 6a. Person does not exist in the list +** 6a1. System informs User that person is not in the list + . User enters invalid input . System tries to predict what the user would have wanted to type . System displays the valid use of input, if found @@ -289,6 +371,7 @@ Use case ends. * 3a. The invalid input is an invalid command. ** 3a1. System also displays the valid usage of the command. + + Use case ends. @@ -298,8 +381,13 @@ Use case ends. + Use case ends. + + +=== Use case: Undo + === Use case: Load messages + *MSS* . User requests to display messages in inbox diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 81879a7cd..5f61f1e66 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -26,12 +26,12 @@ Format: help 3.2. Adding a new person: add Adds a criminal to the database- only by Admin. -Format: add i/NRIC n/NAME p/PHONE_NUMBER d/DATE_OF_BIRTH s/STATUS a/ADDRESS +Format: add NAME n/NRIC d/DATEOFBIRTH p/POSTALCODE s/STATUS w/WANTEDFOR [o/PASTOFFENSES] Examples: -● add i/G1978411Q n/John Doe p/98765432 d/03-April-1972 s/Wanted a/John street, block 123, #01-01 +● add John Doe n/s1234567a d/1996 p/510246 s/xc w/none o/theft o/drugs" 3.3. Editing a person : edit Edits an existing person in the address book. -Format: edit NRIC [n/NAME] [p/PHONE] [d/DATE_OF_BIRTH] [s/STATUS] [a/ADDRESS] +Format: edit n/[NAME] p/[POSTAL_CODE] s/[STATUS] w/WANTED_FOR o/PAST_OFFENCES ● Edits the person with the specified NRIC. ● At least one of the optional fields must be provided. ● Existing values will be updated to the input values. @@ -172,14 +172,14 @@ Output: Dispatch message sent to PO2 Format - help ● Add -Format - add i/[NRIC] n/[NAME] p/[PHONE_NUMBER] d/[DATE_OF_BIRTH] s/[STATUS] a/[ADDRESS] +Format - add n/[NAME] n/[NRIC] d/[DATE_OF_BIRTH] p/[POSTAL_CODE] s/[STATUS] w/WANTED_FOR o/PAST_OFFENCES -E.g. add i/G1978411Q n/John Doe p/98765432 d/03-April-1972 s/Wanted a/John street, block 123, #01-01 +E.g. add John Doe n/s1234567a d/1996 p/510246 s/xc w/none o/theft o/drugs" ● Edit -Format- edit NRIC [n/NAME] [p/PHONE] [d/DATE_OF_BIRTH] [s/STATUS] [a/ADDRESS] +Format- edit n/[NAME] p/[POSTAL_CODE] s/[STATUS] w/WANTED_FOR o/PAST_OFFENCES -E.g. edit G1952866Q p/91234567 +E.g. edit G1952866Q p/510246 ● Delete Format- delete NRIC diff --git a/parserLog.log.1 b/parserLog.log.1 new file mode 100644 index 000000000..0f58090fb --- /dev/null +++ b/parserLog.log.1 @@ -0,0 +1,16 @@ + + + + + 2018-10-14T13:51:33.815695600Z + 1539525093815 + 695600 + 0 + seedu.addressbook.parser.Parser + INFO + seedu.addressbook.parser.Parser + parseCommand + 17 + Parsed the user input and matching commands. + + diff --git a/src/seedu/addressbook/commands/CheckCommand.java b/src/seedu/addressbook/commands/CheckCommand.java new file mode 100644 index 000000000..b8ecd8338 --- /dev/null +++ b/src/seedu/addressbook/commands/CheckCommand.java @@ -0,0 +1,52 @@ +package seedu.addressbook.commands; + + +import seedu.addressbook.data.exception.IllegalValueException; +import seedu.addressbook.data.person.Person; +import seedu.addressbook.data.person.ReadOnlyPerson; +import seedu.addressbook.storage.jaxb.AdaptedAddressBook; +import seedu.addressbook.storage.jaxb.AdaptedPerson; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class CheckCommand extends Command { + + + public static final String COMMAND_WORD = "check"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ":\n" + "Gets screening history of person with specified NRIC \n\t" + + "Parameters: NRIC ...\n\t" + + "Example: " + COMMAND_WORD + " s1234567a"; + private String nricKeyword; + private ReadOnlyPerson matchedPerson; + + + public CheckCommand(String nricToFind) + { + this.nricKeyword = nricToFind; + } + + public String getNricKeyword(){ + return nricKeyword; + } + + + + @Override + public CommandResult execute() { + final List screeningHistory = getPersonWithNric(nricKeyword); + return new CommandResult(getMessageForScreeningHistoryShownSummary(screeningHistory)); + } + + private List getPersonWithNric(String nric){ + List screeningHistory = new ArrayList<>(); + try { + screeningHistory = addressBook.readDatabase(nric); + } catch (IOException e) { + e.printStackTrace(); + } + return screeningHistory; + } + +} diff --git a/src/seedu/addressbook/commands/Command.java b/src/seedu/addressbook/commands/Command.java index 63bad0dd5..c62208243 100644 --- a/src/seedu/addressbook/commands/Command.java +++ b/src/seedu/addressbook/commands/Command.java @@ -1,5 +1,6 @@ package seedu.addressbook.commands; +import seedu.addressbook.Main; import seedu.addressbook.common.Messages; import seedu.addressbook.data.AddressBook; import seedu.addressbook.data.person.*; @@ -9,6 +10,9 @@ import java.util.NoSuchElementException; import java.util.Set; +import seedu.addressbook.ui.Formatter; +import seedu.addressbook.ui.MainWindow; + import static seedu.addressbook.ui.Gui.DISPLAYED_INDEX_OFFSET; /** @@ -39,6 +43,22 @@ public static String getMessageForPersonListShownSummary(List timestampsDisplayed) { + + //TODO: Try format or mainwindow methods + Formatter formatter = new Formatter(); + String result = formatter.formatForTstamps(timestampsDisplayed); + String finalResult = result + String.format(Messages.MESSAGE_TIMESTAMPS_LISTED_OVERVIEW, timestampsDisplayed.size()); + return finalResult; + } + /** * Executes the command and returns the result. */ @@ -75,6 +95,16 @@ protected ReadOnlyPerson getTargetPerson(Name name) throws UniquePersonList.Pers throw new UniquePersonList.PersonNotFoundException(); } + protected ReadOnlyPerson getTargetPersonWithNric(NRIC nric) throws UniquePersonList.PersonNotFoundException { + for (ReadOnlyPerson person: relevantPersons) { + if (person.getNRIC().getIdentificationNumber().equals(nric.getIdentificationNumber())) { + return person; + } + } + throw new UniquePersonList.PersonNotFoundException(); + } + + public int getTargetIndex() { return targetIndex; } diff --git a/src/seedu/addressbook/commands/DeleteCommand.java b/src/seedu/addressbook/commands/DeleteCommand.java index f8dc61ec8..e06ae6f1d 100644 --- a/src/seedu/addressbook/commands/DeleteCommand.java +++ b/src/seedu/addressbook/commands/DeleteCommand.java @@ -1,6 +1,8 @@ package seedu.addressbook.commands; +import com.sun.xml.txw2.NamespaceResolver; import seedu.addressbook.common.Messages; +import seedu.addressbook.data.person.NRIC; import seedu.addressbook.data.person.Name; import seedu.addressbook.data.person.ReadOnlyPerson; import seedu.addressbook.data.person.UniquePersonList.PersonNotFoundException; @@ -16,21 +18,21 @@ public class DeleteCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ":\n" + "Deletes the person by nric.\n\t" + "Parameters: NRIC\n\t" - + "Example: " + COMMAND_WORD + " s1234567"; + + "Example: " + COMMAND_WORD + " s1234567a"; public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; - private Name toDelete; + private NRIC toDelete; public DeleteCommand(int targetVisibleIndex) { super(targetVisibleIndex); } - public DeleteCommand(Name name) { + public DeleteCommand(NRIC nric) { - this.toDelete = name; + this.toDelete = nric; } @@ -38,7 +40,7 @@ public DeleteCommand(Name name) { @Override public CommandResult execute() { try { - final ReadOnlyPerson target = (toDelete == null) ? getTargetPerson() : getTargetPerson(toDelete); + final ReadOnlyPerson target = (toDelete == null) ? getTargetPerson() : getTargetPersonWithNric(toDelete); addressBook.removePerson(target); return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, target)); } catch (IndexOutOfBoundsException ie) { diff --git a/src/seedu/addressbook/commands/FindCommand.java b/src/seedu/addressbook/commands/FindCommand.java index d780cb68f..2ad3d9cc1 100644 --- a/src/seedu/addressbook/commands/FindCommand.java +++ b/src/seedu/addressbook/commands/FindCommand.java @@ -5,7 +5,10 @@ import seedu.addressbook.data.person.Person; import seedu.addressbook.data.person.ReadOnlyPerson; +import java.io.IOException; +import java.sql.Time; import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.util.*; /** @@ -16,45 +19,55 @@ public class FindCommand extends Command { public static final String COMMAND_WORD = "find"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ":\n" + "Finds all persons whose names contain any of " - + "the specified keywords (case-sensitive) and displays them as a list with index numbers.\n\t" - + "Parameters: KEYWORD [MORE_KEYWORDS]...\n\t" - + "Example: " + COMMAND_WORD + " alice bob charlie"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ":\n" + "Finds person with specified NRIC \n\t" + + "Parameters: NRIC ...\n\t" + + "Example: " + COMMAND_WORD + " s1234567a"; - private final Set keywords; + //private final Set nricToFind; + private String nricKeyword; - public FindCommand(Set keywords) { - this.keywords = keywords; + public FindCommand(String nricToFind) + { + this.nricKeyword = nricToFind; } - /** - * Returns copy of keywords in this command. - */ - public Set getKeywords() { - return new HashSet<>(keywords); +// /** +// * Returns copy of the nric in this command. +// */ +// public Set getNricToFind() { +// return new HashSet<>(nricToFind); +// } + + public String getNricKeyword(){ + return nricKeyword; } @Override public CommandResult execute() { - final List personsFound = getPersonsWithNameContainingAnyKeyword(keywords); + final List personsFound = getPersonsWithNric(nricKeyword); return new CommandResult(getMessageForPersonListShownSummary(personsFound), personsFound); } /** * Retrieve all persons in the address book whose names contain some of the specified keywords. * - * @param keywords for searching + * @param nric for searching * @return list of persons found */ - private List getPersonsWithNameContainingAnyKeyword(Set keywords) { - final List matchedPersons = new ArrayList<>(); - for (ReadOnlyPerson person : addressBook.getAllPersons()) { - final Set wordsInName = new HashSet<>(person.getName().getWordsInName()); - if (!Collections.disjoint(wordsInName, keywords)) { - matchedPersons.add(person); + private List getPersonsWithNric(String nric){ + final List matchedPerson = new ArrayList<>(); + for (ReadOnlyPerson person : addressBook.getAllPersonsDirect()) { + if (person.getNRIC().getIdentificationNumber().equals(nric)) { + matchedPerson.add(person); + addressBook.addPersontoDbAndUpdate(person); + try { + addressBook.updateDatabase(); + } catch (IOException e) { + e.printStackTrace(); + } } } - return matchedPersons; + return matchedPerson; } } diff --git a/src/seedu/addressbook/common/Messages.java b/src/seedu/addressbook/common/Messages.java index d1a8fc529..165ac2611 100644 --- a/src/seedu/addressbook/common/Messages.java +++ b/src/seedu/addressbook/common/Messages.java @@ -9,6 +9,7 @@ public class Messages { public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; public static final String MESSAGE_PERSON_NOT_IN_ADDRESSBOOK = "Person could not be found in system"; public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; + public static final String MESSAGE_TIMESTAMPS_LISTED_OVERVIEW = "%1$d time(s) screened"; public static final String MESSAGE_PROGRAM_LAUNCH_ARGS_USAGE = "Launch command format: " + "java seedu.addressbook.Main [STORAGE_FILE_PATH]"; public static final String MESSAGE_WELCOME = "Welcome to your system."; diff --git a/src/seedu/addressbook/data/AddressBook.java b/src/seedu/addressbook/data/AddressBook.java index d3c4b38c3..a2df26bbb 100644 --- a/src/seedu/addressbook/data/AddressBook.java +++ b/src/seedu/addressbook/data/AddressBook.java @@ -1,16 +1,29 @@ package seedu.addressbook.data; +import seedu.addressbook.data.person.NRIC; import seedu.addressbook.data.person.Person; import seedu.addressbook.data.person.ReadOnlyPerson; import seedu.addressbook.data.person.UniquePersonList; import seedu.addressbook.data.person.UniquePersonList.DuplicatePersonException; import seedu.addressbook.data.person.UniquePersonList.PersonNotFoundException; +import java.io.*; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.*; + /** * Represents the entire address book. Contains the data of the address book. */ public class AddressBook { + public static final String SCREENING_DATABASE = "ScreeningHistory.txt"; + public static Timestamp screeningTimeStamp; + private static final SimpleDateFormat timestampFormatter = new SimpleDateFormat("dd/MM/yyyy-HH:mm:ss"); + private String tempNric; + private String tempTimestamp; + private int counter = 0; + private final UniquePersonList allPersons; public static AddressBook empty() { @@ -40,6 +53,64 @@ public AddressBook(UniquePersonList persons) { */ public void addPerson(Person toAdd) throws UniquePersonList.DuplicateNricException { allPersons.add(toAdd); + } + + public void addPersontoDbAndUpdate(ReadOnlyPerson toAdd) { + tempNric = toAdd.getNRIC().getIdentificationNumber(); + screeningTimeStamp = new Timestamp(System.currentTimeMillis()); + tempTimestamp = timestampFormatter.format(screeningTimeStamp); + } + + public List readDatabase(String nric) throws IOException { + List data = new ArrayList<>(); + String line; + BufferedReader br = new BufferedReader(new FileReader(SCREENING_DATABASE)); + line = br.readLine(); + while (line != null){ + String[] parts = line.split(" "); + if (parts[0].equals(nric)){ + data.add(parts[1]); + line = br.readLine(); + } + else{ + line = br.readLine(); + } + } + return data; + } + + public void updateDatabase() throws IOException { + String line; + BufferedReader br = new BufferedReader(new FileReader(SCREENING_DATABASE)); + FileWriter write = new FileWriter(SCREENING_DATABASE,true); + PrintWriter myPrinter = new PrintWriter(write); + try { + while ((line = br.readLine()) != null){ + String[] parts = line.split(" "); + if (parts[0].equals(tempNric)){ + myPrinter.println(tempNric + " " + tempTimestamp); + myPrinter.close(); + br.close(); + return; + } + line = br.readLine(); + continue; + } + myPrinter.println(tempNric + " " + tempTimestamp); + myPrinter.close(); + br.close(); + } + catch (Exception e){ + myPrinter.print(tempNric + " " + tempTimestamp); + + myPrinter.close(); + br.close(); + } + + + + + } /** @@ -49,6 +120,7 @@ public boolean containsPerson(ReadOnlyPerson key) { return allPersons.contains(key); } + /** * Removes the equivalent person from the address book. * @@ -83,6 +155,10 @@ public UniquePersonList getAllPersons() { return new UniquePersonList(allPersons); } + public UniquePersonList getAllPersonsDirect() { + return allPersons; + } + @Override public boolean equals(Object other) { return other == this // short circuit if same object diff --git a/src/seedu/addressbook/data/person/NRIC.java b/src/seedu/addressbook/data/person/NRIC.java index 9654b0b7d..8ef43ffd9 100644 --- a/src/seedu/addressbook/data/person/NRIC.java +++ b/src/seedu/addressbook/data/person/NRIC.java @@ -12,9 +12,9 @@ public class NRIC { public static final String EXAMPLE = "s1234567a"; - public static final String MESSAGE_NAME_CONSTRAINTS = "NRIC/FIN should start with 's'/'t'/'g'/'f' and end with a letter and " + + public static final String MESSAGE_NAME_CONSTRAINTS = "NRIC/FIN should start with 's'/'t'/'g'/'f'(lower case) and end with a letter and " + "must have 7 digits in between, no spaces"; - public static final String NAME_VALIDATION_REGEX = "[sStTgGfF][0-9]{7}[a-zA-Z]"; + public static final String NAME_VALIDATION_REGEX = "[stgf][0-9]{7}[a-z]"; public final String identificationNumber; diff --git a/src/seedu/addressbook/data/person/Person.java b/src/seedu/addressbook/data/person/Person.java index 193ebeacd..607f86b75 100644 --- a/src/seedu/addressbook/data/person/Person.java +++ b/src/seedu/addressbook/data/person/Person.java @@ -21,13 +21,14 @@ public class Person implements ReadOnlyPerson { private Status status; private Offense wantedFor; - private final Set PastOffense = new HashSet<>(); + private Set PastOffense = new HashSet<>(); public static String WANTED_FOR_WARNING = "State the offence if person's status is wanted"; - private Set screeningHistory; + public static Timestamp screeningTimeStamp; + private static final SimpleDateFormat timestampFormatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); /** * Assumption: Every field must be present and not null. @@ -66,6 +67,8 @@ public Person(ReadOnlyPerson source) throws IllegalValueException { source.getWantedFor(), source.getPastOffense()); } + + @Override public Name getName() { return name; @@ -97,9 +100,6 @@ public Offense getWantedFor() { @Override public Set getPastOffense() {return PastOffense;} - @Override - public Set getScreeningHistory() {return screeningHistory;} - /** * Replaces this person's tags with the tags in {@code replacement}. */ diff --git a/src/seedu/addressbook/data/person/ReadOnlyPerson.java b/src/seedu/addressbook/data/person/ReadOnlyPerson.java index 7c878885a..1a2d39ac1 100644 --- a/src/seedu/addressbook/data/person/ReadOnlyPerson.java +++ b/src/seedu/addressbook/data/person/ReadOnlyPerson.java @@ -25,7 +25,7 @@ public interface ReadOnlyPerson { * changes on the returned list will not affect the person's internal tags. */ Set getPastOffense(); - Set getScreeningHistory(); + /** * Returns true if the values inside this object is same as those of the other (Note: interfaces cannot override .equals) */ @@ -63,28 +63,6 @@ default String getAsTextShowAll() { return builder.toString(); } - /** - * Formats a person as text, showing only non-private contact details. - */ - /** - default String getAsTextHidePrivate() { - final StringBuilder builder = new StringBuilder(); - builder.append(getName()) - .append(" NRIC: "); - builder.append(getNRIC()) - .append(" DateOfBirth: "); - builder.append(getDateOfBirth()) - .append(" Postal Code"); - builder.append(getPostalCode()) - .append(" Status: "); - builder.append(getStatus()) - .append(" Wanted For: "); - builder.append(getWantedFor()) - .append(" Past Offences:"); - for (Offense offense : getPastOffense()) { - builder.append(offense); - } - return builder.toString(); - } - */ + + } diff --git a/src/seedu/addressbook/data/person/UniquePersonList.java b/src/seedu/addressbook/data/person/UniquePersonList.java index 5e85a4cc0..942ab8692 100644 --- a/src/seedu/addressbook/data/person/UniquePersonList.java +++ b/src/seedu/addressbook/data/person/UniquePersonList.java @@ -3,6 +3,8 @@ import seedu.addressbook.common.Utils; import seedu.addressbook.data.exception.DuplicateDataException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.util.*; /** @@ -16,6 +18,9 @@ public class UniquePersonList implements Iterable { /** * Signals that an operation would have violated the 'no duplicates' property of the list. */ + public static Timestamp screeningTimeStamp; + private static final SimpleDateFormat timestampFormatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); + public static class DuplicatePersonException extends DuplicateDataException { protected DuplicatePersonException() { super("Operation would result in duplicate persons"); diff --git a/src/seedu/addressbook/parser/Parser.java b/src/seedu/addressbook/parser/Parser.java index 2b921a73c..ceb8d8d54 100644 --- a/src/seedu/addressbook/parser/Parser.java +++ b/src/seedu/addressbook/parser/Parser.java @@ -6,6 +6,7 @@ import seedu.addressbook.commands.*; import seedu.addressbook.common.Utils; import seedu.addressbook.data.exception.IllegalValueException; +import seedu.addressbook.data.person.NRIC; import seedu.addressbook.data.person.Name; import java.io.IOException; @@ -37,6 +38,7 @@ public class Parser { + "(?(?: o/[^/]+)*)"); // variable number of offenses public static final Pattern PERSON_NAME_FORMAT = Pattern.compile("(?[^/]+)"); + public static final Pattern PERSON_NRIC_FORMAT = Pattern.compile("(?[^/]+)"); /** * Signals that the user input could not be parsed. @@ -141,7 +143,10 @@ public Command parseCommand(String userInput) { return new ClearCommand(); case FindCommand.COMMAND_WORD: - return prepareFind(arguments); + return prepareFindOrCheck(arguments,false); + + case CheckCommand.COMMAND_WORD: + return prepareFindOrCheck(arguments,true); case ListCommand.COMMAND_WORD: return new ListCommand(); @@ -219,13 +224,13 @@ private static Set getTagsFromArgs(String tagArguments) throws IllegalVa */ private Command prepareDelete(String args){ try { - final String name = parseArgsAsName(args); - if (Utils.isStringInteger(name)) { - final int targetIndex = parseArgsAsDisplayedIndex(args); - return new DeleteCommand(targetIndex); - } + final String nric = parseArgsAsNric(args); +// if (Utils.isStringInteger(name)) { +// final int targetIndex = parseArgsAsDisplayedIndex(args); +// return new DeleteCommand(targetIndex); +// } - return new DeleteCommand(new Name(name)); + return new DeleteCommand(new NRIC(nric)); } catch (ParseException e) { logr.log(Level.WARNING, "Invalid delete command format.", e); return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); @@ -332,24 +337,43 @@ private String parseArgsAsName(String args) throws ParseException { return matcher.group(0); } + private String parseArgsAsNric(String args) throws ParseException { + final Matcher matcher = PERSON_NRIC_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + logr.warning("Nric does not exist in argument"); + throw new ParseException("Could not find nric to parse"); + } + return matcher.group(0); + } + /** * Parses arguments in the context of the find person command. * * @param args full command args string * @return the prepared command */ - private Command prepareFind(String args) { - final Matcher matcher = KEYWORDS_ARGS_FORMAT.matcher(args.trim()); - if (!matcher.matches()) { - logr.warning("Argument for finding NRIC is invalid"); - return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, - FindCommand.MESSAGE_USAGE)); + private Command prepareFindOrCheck(String args, boolean isChecking) { + args = args.trim(); + try{ + NRIC keyPerson = new NRIC(args); + + return ((isChecking == true) ? new CheckCommand(args) : new FindCommand(args)); } + catch (IllegalValueException invalidNric){ + logr.warning("NRIC argument is invalid"); + return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT,FindCommand.MESSAGE_USAGE)); + } + + +// +// final Matcher matcher = PERSON_NRIC_FORMAT.matcher(args); +// if (!matcher.matches()) { +// logr.warning("Argument for finding NRIC is invalid"); +// return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, +// FindCommand.MESSAGE_USAGE)); +// } - // keywords delimited by whitespace - final String[] keywords = matcher.group("keywords").split("\\s+"); - final Set keywordSet = new HashSet<>(Arrays.asList(keywords)); - return new FindCommand(keywordSet); + //return new FindCommand(args); } } \ No newline at end of file diff --git a/src/seedu/addressbook/storage/jaxb/AdaptedAddressBook.java b/src/seedu/addressbook/storage/jaxb/AdaptedAddressBook.java index 4a8297ce3..abf8a377a 100644 --- a/src/seedu/addressbook/storage/jaxb/AdaptedAddressBook.java +++ b/src/seedu/addressbook/storage/jaxb/AdaptedAddressBook.java @@ -34,7 +34,6 @@ public AdaptedAddressBook(AddressBook source) { source.getAllPersons().forEach(person -> persons.add(new AdaptedPerson(person))); } - /** * Returns true if any required field is missing. * diff --git a/src/seedu/addressbook/storage/jaxb/AdaptedPerson.java b/src/seedu/addressbook/storage/jaxb/AdaptedPerson.java index 301fa4894..eff214ccb 100644 --- a/src/seedu/addressbook/storage/jaxb/AdaptedPerson.java +++ b/src/seedu/addressbook/storage/jaxb/AdaptedPerson.java @@ -71,6 +71,7 @@ public AdaptedPerson(ReadOnlyPerson source) { for (Offense tag : source.getPastOffense()) { tagged.add(new AdaptedTag(tag)); } + } /** @@ -99,9 +100,12 @@ public boolean isAnyRequiredFieldMissing() { */ public Person toModelType() throws IllegalValueException { final Set tags = new HashSet<>(); + for (AdaptedTag tag : tagged) { tags.add(tag.toModelType()); } + Set screeningHistory = new HashSet<>(); + final Name name = new Name(this.name); final NRIC nric = new NRIC(this.nric.value); final DateOfBirth dateOfBirth = new DateOfBirth(this.dateOfBirth.value); diff --git a/src/seedu/addressbook/ui/Formatter.java b/src/seedu/addressbook/ui/Formatter.java index ea23b5b30..325f84452 100644 --- a/src/seedu/addressbook/ui/Formatter.java +++ b/src/seedu/addressbook/ui/Formatter.java @@ -43,6 +43,14 @@ public String format(List persons) { return format(asIndexedList(formattedPersons)); } + public String formatForTstamps(List timestamps) { + final List formattedTimestamps = new ArrayList<>(); + for (String timestamp : timestamps) { + formattedTimestamps.add(timestamp); + } + return format(asIndexedList(formattedTimestamps)); + } + /** Formats a list of strings as an indexed list. */ private static String asIndexedList(List listItems) { final StringBuilder formatted = new StringBuilder(); diff --git a/src/seedu/addressbook/ui/MainWindow.java b/src/seedu/addressbook/ui/MainWindow.java index 014555fea..dc2eadcd9 100644 --- a/src/seedu/addressbook/ui/MainWindow.java +++ b/src/seedu/addressbook/ui/MainWindow.java @@ -33,6 +33,8 @@ public class MainWindow { public MainWindow(){ } + + public void setLogic(Logic logic){ this.logic = logic; } @@ -374,10 +376,14 @@ private void display(List persons) { display(new Formatter().format(persons)); } + public void displayTimestamps(List history){ + display(new Formatter().formatForTstamps(history)); + } + /** * Displays the given messages on the output display area, after formatting appropriately. */ - private void display(String... messages) { + public void display(String... messages) { outputConsole.setText(outputConsole.getText() + new Formatter().format(messages)); } diff --git a/test/java/seedu/addressbook/logic/LogicTest.java b/test/java/seedu/addressbook/logic/LogicTest.java index 8a0ad0f9b..7981c32c6 100644 --- a/test/java/seedu/addressbook/logic/LogicTest.java +++ b/test/java/seedu/addressbook/logic/LogicTest.java @@ -241,6 +241,19 @@ private void assertInvalidIndexBehaviorForCommand(String commandWord) throws Exc } + private void assertInvalidCommandFormatBehaviorForCommand(String commandWord) throws Exception { + String expectedMessage = NRIC.MESSAGE_NAME_CONSTRAINTS; + TestDataHelper helper = new TestDataHelper(); + List lastShownList = helper.generatePersonList(false, true); + + logic.setLastShownList(lastShownList); + + assertCommandBehavior(commandWord + " -1", expectedMessage, AddressBook.empty(), false, lastShownList); + assertCommandBehavior(commandWord + " 0", expectedMessage, AddressBook.empty(), false, lastShownList); + assertCommandBehavior(commandWord + " 3", expectedMessage, AddressBook.empty(), false, lastShownList); + + } + //@Test /* public void execute_view_onlyShowsNonPrivate() throws Exception { @@ -353,30 +366,8 @@ public void execute_delete_invalidArgsFormat() throws Exception { }*/ @Test - public void execute_delete_byName() throws Exception { - TestDataHelper helper = new TestDataHelper(); - - Person p1 = helper.generatePersonWithName("Harun"); - Person p2 = helper.generatePersonWithName("Putra"); - - List twoPersons = helper.generatePersonList(p1, p2); - AddressBook expectedAB = helper.generateAddressBook(twoPersons); - expectedAB.removePerson(p1); - - helper.addToAddressBook(addressBook, twoPersons); - logic.setLastShownList(twoPersons); - - - assertCommandBehavior("delete Harun", - String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, p1), - expectedAB, - false, - twoPersons); - } - - @Test - public void execute_delete_invalidIndex() throws Exception { - assertInvalidIndexBehaviorForCommand("delete"); + public void execute_delete_invalidCommandFormat() throws Exception { + assertInvalidCommandFormatBehaviorForCommand("delete"); } @Test @@ -395,7 +386,7 @@ public void execute_delete_removesCorrectPerson() throws Exception { helper.addToAddressBook(addressBook, threePersons); logic.setLastShownList(threePersons); - assertCommandBehavior("delete 2", + assertCommandBehavior("delete g9999992t", String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, p2), expectedAB, false, @@ -419,7 +410,7 @@ public void execute_delete_missingInAddressBook() throws Exception { addressBook.removePerson(p2); logic.setLastShownList(threePersons); - assertCommandBehavior("delete 2", + assertCommandBehavior("delete g9999992t", Messages.MESSAGE_PERSON_NOT_IN_ADDRESSBOOK, expectedAB, false, @@ -440,68 +431,69 @@ public void execute_delete_missingInAddressBook() throws Exception { @Test public void execute_find_invalidArgsFormat() throws Exception { String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE); - assertCommandBehavior("find ", expectedMessage); - } - - @Test - public void execute_find_onlyMatchesFullWordsInNames() throws Exception { - TestDataHelper helper = new TestDataHelper(); - Person pTarget1 = helper.generatePersonWithName("bla bla KEY bla"); - Person pTarget2 = helper.generatePersonWithName("bla KEY bla bceofeia"); - Person p1 = helper.generatePersonWithName("KE Y"); - Person p2 = helper.generatePersonWithName("KEYKEYKEY sduauo"); - - List fourPersons = helper.generatePersonList(p1, pTarget1, p2, pTarget2); - AddressBook expectedAB = helper.generateAddressBook(fourPersons); - List expectedList = helper.generatePersonList(pTarget1, pTarget2); - helper.addToAddressBook(addressBook, fourPersons); - - assertCommandBehavior("find KEY", - Command.getMessageForPersonListShownSummary(expectedList), - expectedAB, - true, - expectedList); + assertCommandBehavior("find S1234567A", expectedMessage); } @Test - public void execute_find_isCaseSensitive() throws Exception { + public void execute_find_onlyMatchesFullNric() throws Exception { TestDataHelper helper = new TestDataHelper(); - Person pTarget1 = helper.generatePersonWithName("bla bla KEY bla"); - Person pTarget2 = helper.generatePersonWithName("bla KEY bla bceofeia"); - Person p1 = helper.generatePersonWithName("key key"); - Person p2 = helper.generatePersonWithName("KEy sduauo"); + Person pTarget1 = helper.generatePersonWithNric("s1234567a"); + Person pTarget2 = helper.generatePersonWithNric("s1234567b"); + Person p1 = helper.generatePersonWithNric("s1234567c"); + Person p2 = helper.generatePersonWithNric("s1234567d"); List fourPersons = helper.generatePersonList(p1, pTarget1, p2, pTarget2); AddressBook expectedAB = helper.generateAddressBook(fourPersons); - List expectedList = helper.generatePersonList(pTarget1, pTarget2); + List expectedList = helper.generatePersonList(pTarget2); helper.addToAddressBook(addressBook, fourPersons); - assertCommandBehavior("find KEY", + assertCommandBehavior("find s1234567b", Command.getMessageForPersonListShownSummary(expectedList), expectedAB, true, expectedList); } - @Test - public void execute_find_matchesIfAnyKeywordPresent() throws Exception { - TestDataHelper helper = new TestDataHelper(); - Person pTarget1 = helper.generatePersonWithName("bla bla KEY bla"); - Person pTarget2 = helper.generatePersonWithName("bla rAnDoM bla bceofeia"); - Person p1 = helper.generatePersonWithName("key key"); - Person p2 = helper.generatePersonWithName("KEy sduauo"); - - List fourPersons = helper.generatePersonList(p1, pTarget1, p2, pTarget2); - AddressBook expectedAB = helper.generateAddressBook(fourPersons); - List expectedList = helper.generatePersonList(pTarget1, pTarget2); - helper.addToAddressBook(addressBook, fourPersons); +// @Test +// public void execute_find_isCaseSensitive() throws Exception { +// TestDataHelper helper = new TestDataHelper(); +// Person pTarget1 = helper.generatePersonWithNric("s1234567b"); +// Person pTarget2 = helper.generatePersonWithNric("s1234567c"); +// Person p1 = helper.generatePersonWithNric("s1234567d"); +// Person p2 = helper.generatePersonWithNric("s1234567e"); +// +// List fourPersons = helper.generatePersonList(p1, pTarget1, p2, pTarget2); +// AddressBook expectedAB = helper.generateAddressBook(fourPersons); +// List expectedList = helper.generatePersonList(pTarget1, pTarget2); +// helper.addToAddressBook(addressBook, fourPersons); +// String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE); +// assertCommandBehavior("find S1234567B", +// Command.getMessageForPersonListShownSummary(expectedList), +// expectedAB, +// true, +// expectedList); +// +// } - assertCommandBehavior("find KEY rAnDoM", - Command.getMessageForPersonListShownSummary(expectedList), - expectedAB, - true, - expectedList); - } +// @Test +// public void execute_find_matchesIfAnyKeywordPresent() throws Exception { +// TestDataHelper helper = new TestDataHelper(); +// Person pTarget1 = helper.generatePersonWithName("bla bla KEY bla"); +// Person pTarget2 = helper.generatePersonWithName("bla rAnDoM bla bceofeia"); +// Person p1 = helper.generatePersonWithName("key key"); +// Person p2 = helper.generatePersonWithName("KEy sduauo"); +// +// List fourPersons = helper.generatePersonList(p1, pTarget1, p2, pTarget2); +// AddressBook expectedAB = helper.generateAddressBook(fourPersons); +// List expectedList = helper.generatePersonList(pTarget1, pTarget2); +// helper.addToAddressBook(addressBook, fourPersons); +// +// assertCommandBehavior("find KEY rAnDoM", +// Command.getMessageForPersonListShownSummary(expectedList), +// expectedAB, +// true, +// expectedList); +// } /** * A utility class to generate test data. @@ -633,7 +625,23 @@ String generateRandomNric() { int min = 1111111; int max = 9999999; Random r = new Random(); - return "S"+Integer.toString(r.nextInt((max - min) + 1) + min)+"A"; + return "s"+Integer.toString(r.nextInt((max - min) + 1) + min)+"a"; + } + + /** + * Generates a Person object with given nric. Other fields will have some dummy values. + */ + + Person generatePersonWithNric(String nric) throws Exception { + return new Person( + new Name("Bob"), + new NRIC(nric), + new DateOfBirth("2005"), + new PostalCode("123456"), + new Status("xc"), + new Offense(), + Collections.singleton(new Offense("riot")) + ); } /** diff --git a/test/java/seedu/addressbook/parser/ParserTest.java b/test/java/seedu/addressbook/parser/ParserTest.java index 4778140ee..7bed5485e 100644 --- a/test/java/seedu/addressbook/parser/ParserTest.java +++ b/test/java/seedu/addressbook/parser/ParserTest.java @@ -83,13 +83,13 @@ public void deleteCommand_noArgs() { // parseAndAssertIncorrectWithMessage(resultMessage, inputs); // } - @Test - public void deleteCommand_numericArg_indexParsedCorrectly() { - final int testIndex = 1; - final String input = "delete " + testIndex; - final DeleteCommand result = parseAndAssertCommandType(input, DeleteCommand.class); - assertEquals(result.getTargetIndex(), testIndex); - } +// @Test +// public void deleteCommand_numericArg_indexParsedCorrectly() { +// final int testIndex = 1; +// final String input = "delete " + testIndex; +// final DeleteCommand result = parseAndAssertCommandType(input, DeleteCommand.class); +// assertEquals(result.getTargetIndex(), testIndex); +// } /*@Test public void viewCommand_noArgs() { @@ -155,25 +155,27 @@ public void findCommand_invalidArgs() { @Test public void findCommand_validArgs_parsedCorrectly() { - final String[] keywords = { "key1", "key2", "key3" }; - final Set keySet = new HashSet<>(Arrays.asList(keywords)); - - final String input = "find " + String.join(" ", keySet); + //final String[] keywords = { "key1", "key2", "key3" }; + //final Set keySet = new HashSet<>(Arrays.asList(keywords)); + final String keyword = "s1234567a"; + final String input = "find " + keyword; final FindCommand result = parseAndAssertCommandType(input, FindCommand.class); - assertEquals(keySet, result.getKeywords()); + assertEquals(keyword, result.getNricKeyword()); } @Test public void findCommand_duplicateKeys_parsedCorrectly() { - final String[] keywords = { "key1", "key2", "key3" }; - final Set keySet = new HashSet<>(Arrays.asList(keywords)); - +// final String[] keywords = { "key1", "key2", "key3" }; +// final Set keySet = new HashSet<>(Arrays.asList(keywords)); + final String keyword = "s1234567a"; // duplicate every keyword - final String input = "find " + String.join(" ", keySet) + " " + String.join(" ", keySet); - final FindCommand result = - parseAndAssertCommandType(input, FindCommand.class); - assertEquals(keySet, result.getKeywords()); + final String input = "find " + keyword + " " + keyword; +// final FindCommand result = +// parseAndAssertCommandType(input, FindCommand.class); + final String resultMessage = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE); + parseAndAssertIncorrectWithMessage(resultMessage, input); } /**