PROJECT: CorpPro


Overview

CorpPro is an address book application that allows you as a corporate user to better manage your contacts and assist in your daily work tasks. The primary interaction between you and application is done through a command line interface that is designed to allow you to do more with less typing. It also has a graphical user interface that provides you with intuitive visual feedbacks. The application is written in Java and JavaFX. This portfolio is to document the contributions I have made to this address book project. It contains descriptions and explanations of various features I have implemented and enhanced.

Summary of contributions

  • Major enhancement 1: Added predictive text typing to allow faster commands input.

    • What it does: Allows users to complete a single line of command by predicting the next sequence of texts.

    • Justification: Some commands may be long winded (eg. a particularly long name) and users may take longer time to type character by character. This feature will allow users to save a lot of time by eliminating such long winded typing.

    • Highlights: This feature is designed to work with the existing commands as well as commands that could be added in future. It utilises data structure concepts I have learned in other university modules to solve the problem of predictive typing.

    • Credits: This feature was inspired by the tab completion feature that exists in bash shell programs.

  • Major enhancement 2: Added ability to email contacts so user can communicate with them via email.

    • What it does: Allows users to email your contacts using a dedicated email application in their computer.

    • Justification: Corportate users regularly need to communicate with their colleagues/clients through email. This feature enables the user to quickly email the target recipients from the address book.

    • Highlights: This feature will work on various common and mainstream operating systems and opens the email application the use commonly uses. This feature gave the opportunity for me to learn and use several built-in Java library classes.

  • Minor enhancements:

    • Improved the select command so users can select a single or multiple contacts.

    • Improved the delete command so users can delete a single or multiple contacts.

    • Improved the list command so users can list contacts filtered by certain attributes.

  • Code contributed: [Reposense][GitHub Pull Requests]

  • Other contributions:

    • Project management:

      • Managed releases v1.1 - v1.4 (4 releases) on GitHub.

      • Drafted agendas and minutes for weekly meetings.

      • Created project (user stories) in team’s GitHub organisation page.

      • Managed Issue tracker and Pull Requests on GitHub.

    • Documentation:

      • Adapted original User Guide and Developer Guide to suit CorpPro.

      • Updated Features section of User Guide with the minor enhancements (select, delete, list commands).

    • Community:

    • Tools:

      • Integrated a new Github plugin (Travis CI) to the team repo.

      • Enabled auto publishing of documents in team repo.

Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

Listing all persons : list

Displays a list of persons in your address book.
Format: list or list t/TAG or list k/KPI

  • t/TAG flag can be specified with a tag to list all persons belonging to that tag.

  • k/KPI flag can be specified with a KPI value to list all persons with that value.

  • If no flags are specified, all persons are listed by default.

Example:

  • You can input list t/HumanResource to display all persons with HumanResource tag in your address book.

Selecting a person : select

Selects a single or multiple contacts identified by their index number in the contacts list displayed on the left.
Format: select INDEX or select START_INDEX - END_INDEX

  • The contact you selected will have their information loaded in the information panel displayed in the centre.

  • The INDEX refers to the index number to left of each contact entry shown in the displayed person list.

  • You must enter positive integers 1, 2, 3, …​ for the INDEX.

  • In the case of multiple selections, the range is denoted with a dash ( - ) and you can separate multiple ranges with comma ( , ).

Examples:

  • list
    select 2
    Selects the 2nd contact in the address book.

  • list
    select 1 - 3
    Selects the 1st to the 3rd contact in the address book.

  • list
    select 1 - 3, 6 - 9
    Selects the 1st to the 3rd contact and 6th to the 9th contact in the address book.

  • find n/Betsy
    select 1
    Selects the 1st contact in the results of the find command.

Selecting a person : delete

Deletes a single or multiple contacts identified by their index number in the contacts list displayed on the left.
Format: delete INDEX or delete START_INDEX - END_INDEX

  • Deletes the contact at the specified INDEX.

  • The INDEX refers to the index number to left of each contact entry shown in the displayed person list.

  • You must enter positive integers 1, 2, 3, …​ for the INDEX.

  • In the case of multiple deletions, the range is denoted with a dash ( - ) and you can separate multiple ranges with comma ( , ).

Examples:

  • list
    delete 2
    Deletes the 2nd contact in the address book.

  • list
    delete 1 - 3
    Deletes the 1st to the 3rd contact in the address book.

  • list
    delete 1 - 3, 6 - 9
    Deletes the 1st to the 3rd contact and 6th to the 9th contact in the address book.

  • find n/Betsy
    delete 1
    Deletes the 1st contact in the results of the find command.

Email contacts : mail

Opens your system’s default email application with specified contacts as recipients.
Format: mail all/ or mail t/TAG or mail

  • all/ flag can be specified to open the email application with all contacts as recipients.

  • t/TAG flag can be specified with a tag to open the email applications with all contacts belonging to that tag as recipients.

  • If no flags are specified, contacts selected with select command are chosen as recipients.

Examples:

  • mail all/
    opens your email application with all contacts as recipients.

  • mail t/accountant
    opens your email application with contacts tagged with accountant as recipients.

  • select 3
    mail
    opens your email application with person (3rd person in the list panel) as recipient.

Text prediction

Text prediction feature allows you to complete your command faster with less typing.
Invoke this feature by pressing the Tab key on the keyboard.

You can invoke this feature on most command keywords and arguments:

  • Command keywords (mail, add, find, etc.) .

  • Flag arguments (n/, a/, t/, etc.) .

For example, given an address book consisting of a contact with the name Alex Yeoh:
Typing m in the box and pressing Tab will auto complete to the mail command. Then, typing mail n/A and pressing Tab will auto complete to mail n/Alex Yeoh for you.

  • If there are multiple predicted values, they will be listed down.

  • If no argument flags are specified, the default value predicted is based on the command’s default argument.

  • This feature does not work with some flag arguments when used with certain commands. E.g. add n/Alex.
    If text prediction returns no predictions, it means text prediction is unsupported in that context. For full list, refer below.

List of commands and it’s arguments prefix supported:

  • list : t/, k/

  • find : n/, e/, p/, a/, t/, k/, r/

  • mail : t/, all/

  • For the remaining commands, all command keywords are supported but their arguments are unsupported.

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

Text Prediction

Current Implementation

The text prediction feature is facilitated mainly by 2 classes, CommandCompleter and Trie. Trie contains the underlying data structure with a set of operations that allows predictions to be retrieved. CommandCompleter manages several instances of that data structure such that predictions of different attributes (name, email, address, etc.) and command keywords (add, edit, etc.) can be made.

For Trie, following operations are implemented:

  • Trie#insert(String value) — inserts a string into the data structure.

  • Trie#remove(String value) — removes a string from the data structure.

  • Trie#getPredictList(String prefix) — retrieves a list of predicted string values that completes the prefix.

For CommandCompleter, following operations are implemented:

  • CommandCompleter#insertPerson() — inserts a Person’s attributes into respective data structure instances.

  • CommandCompleter#removePerson() — removes a Person’s attributes from respective data structure instances.

  • CommandCompleter#editPerson() — edits a Person’s attributes in each data structure instances.

  • CommandCompleter#predictText() — predicts a list of possible text outputs that will complete and append to the given text input.

  • CommandCompleter#clearData() — clears all data structure instances of their data.

Given below is an example usage scenario and how the text prediction mechanism behaves on a high level. For low level implementation details, refer to [TextPredictionDetails].

Step 1. User launches the application. CommandCompleter is instantiated and will initialise all Trie instances with all command keywords and every existing contact’s (aka Person) attributes (name, phone, address, etc.).

Step 2. The user keys in find n/Al into the command box and presses Tab. This will invoke predictText(). The method will subsequently determine (assisted by several helper classes) which Trie instance to retrieve the predictions from. That Trie instance then returns a list of possible predictions, in this case, a list containing ex Yeoh.

Step 3. The user decides to add a new contact with the name Alex Tan using the add command. In the add logic, the method Model#insertPersonIntoPrediction(Person person) will be called which will call the insertPerson() method. This method inserts the contact’s (Alex Tan) attributes into the respective Trie instances.

Step 4. The user decides to predict find n/Al again. The logic sequence is similar to Step 2. However, since a new contact was added in Step 3, instead of returning ex Yeoh only, the returning list will contain both ex Yeoh and ex Tan.

Step 5. The user now decides to remove the contact with the name Alex Yeoh from the address book using the delete 1 command. The removePerson() method will be called and removes that contact’s (Alex Yeoh) attributes from the respective Trie instances.

Step 6. The user decides to predict find n/Al again. Similar to Step 4 except that Alex Yeoh has been removed, the list returned will contain only ex Tan.

Step 7. The user decides to clear the address book with clear command which invokes clearData() method. This clears all attributes data in all Trie instances.

Step 8. The user wants to predict find n/Al again. However since all data were cleared, the returned predictions list contains no entries. No predictions are displayed in feedback panel.

The sequence diagram below demonstrates how the predictText() method will work:

predictText sequence

Design Considerations

Aspect: Data structure used to support text prediction
  • Alternative 1 (current choice): Use a Directed Acyclic Graph to store strings.

    • Pros: Results in greater computational efficiency than the naive approach (Alternative 2).

    • Cons: Much more difficult to implement and prone to bugs.

  • Alternative 2: Use a simple list to store strings.

    • Pros: Much more easier and simple to implement.

    • Cons: Inefficient and takes longer time to retrive the strings. Since the address book can potentially contain large number of contacts, retrieval of strings may take too long, which results in a slow application.

Email Contacts

Current Implementation

The email feature is facilitated by the MailCommand class. It is assisted by the MailCommandParser class to determine the mailType (who to email to) based on the user input. It is also supported by the Java built-in Desktop class to open the user system’s email application using the mail type as the recipients. It implements the following operation:

  • MailCommand#execute() - opens user system’s email application based on the mailType.

Given below is an example usage scenario and how the email mechanism behaves at each step:

Step 1. The user selects contact with the index 1 using the select command.

Step 2. The user inputs mail into the command box and executes the command. execute() checks if the user system is supported by the Java Desktop library and throws an exception if unsupported. In this case, the mailType is contacts selection type. Hence, MailCommand#mailToSelection() is invoked. The Uniform Resource Identifier (URI) is built and Desktop#mail(URI uri) is called, which opens up the system’s email application.

If the user decides to email all contacts with the tag coworker instead, the user will execute mail t/coworker in the command box. Similar to Step 2, except that the logic calls MailCommand#mailToGroups(Model model, Tag tag) with the input tag as parameter. URI is built with contacts containing the specified tag and the email application opens up.