PROJECT: CorpPro


Overview

CorpPro is a desktop address book application which targets small to medium corporates to allow their employees to keep track of colleague information in the office. CorpPro allows users to add, edit and tag with the Command Line Interface (CLI) or the Graphical User Interface (GUI), that is created with JavaFX. This portfolio contains the contributions I had made towards the improvement of the basic Address Book provided to us.

Summary of contributions

  • Major enhancement 1: added the ability to export and import your contacts.

    • What it does: Allows the user to export contacts to a CSV file to any existing directory. Vice versa, CSV files can also be imported from any existing directory and be added to the address book.

    • Justification: Enables users to shift between computer systems with ease.

    • Highlights: In order to ensure that the exported file is compatible with other applications.
      Imported files have to be properly parsed to retrieve contacts.

  • Major enhancement 2: added the ability to back up and restore your address book.

    • What it does: Allow the user to back up their address book at any point in time. This allows them to revert their address book to any previous state if they wish to.

    • Justification: This feature allows the user to retrieve any lost information if they have accidentally deleted any.

    • Highlights: Precautionary measures have to be done as saving the folders in a separate directory will result in the database being compromise. Therefore, we have to protect the folder the backups are saved by making the directory unknown.

  • Code contributed: [RepoSense] [Pull Requests]

  • Other contributions:

    • Project management:

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

    • Enhancements to existing features:

      • Wrote additional tests for existing features to increase coverage from 71% to 86% (Pull requests #123, #158)

      • Issues resolved [Issues]

    • Documentation:

      • Did cosmetic tweaks to existing contents of the User Guide: #158

    • Community:

      • PRs reviewed (with non-trivial review comments): #17

      • Reported bugs and suggestions for other teams in the class

Contributions to the User Guide

Given below are sections I contributed to the User Guide. I have added the description of all the features i have implemented and added a appendix which helps the user to understand how a CSV file works.

Backing up all data : backup

The backup feature allows you to backup your address book and save the state for future restoration.
Format: backup

Restore data from backup : restore

The restore feature allows you to revert your address book back to a specific state in time (provided you backed up the state).
To list out all the available backups from latest to earliest:
Format: restore-snapshots

  • The time of backup is in the format of INDEX d MMM uuuu HH:mm:ss.

  • Example: 1. 29 Oct 2018 00:16:31

To restore your address book to the snapshot denoted by the INDEX,
Format: restore INDEX

  • INDEX refers to the index number denoting the date and time of the backup snapshot.

  • The INDEX must be a positive integer 1, 2, 3, …​

Exports the address book to a directory : export

You can export your address book contacts into a CSV file into any existing directory.
Format: export [d/ OUTPUT_PATH] [f/ NAME_OF_FILE]

  • OUTPUT_PATH is the directory you want to export your contacts to.

  • NAME_OF_FILE is the name of the CSV file exported.

  • If OUTPUT_PATH is not specified, it will create a exports folder and export into it.

  • If NAME_OF_FILE is not specified, it will export to a CSV file named export.csv.

Refer to Format of an exported CSV file for details of an exported CSV file.

Imports the address book from a directory : import

You can import a CSV file and append it to your current address book.
Format: import d/ TARGET_PATH f/ NAME_OF_FILE

  • TARGET_PATH is the directory you want to import your file from.

  • NAME_OF_FILE is the name of the CSV file you want to import.

Appendix A: Format of an exported CSV file

For more information about CSV files, you can refer to CSV file

When an address book is exported, it will be exported into a CSV file which can be read by excel or spreadsheet applications.

Each row refers to a person.
Each column refers to a separate field of the person.

CSV Format

Figure 1. Sample of a CSV file.

If a compulsory field is left blank, the address book will not allow the CSV file to be imported.

  • Compulsory field includes: Name, Phone, Email and Address.

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. I have written on the logic behind on how I have implemented the features that were tasked to me. It also showcases my ability to draw sequence diagrams.

Back Up and Restore

Current implementation of backup

Creation of backups is done in BackUpCommand class. It extends the Command class with an overriding execute function.

Model

This feature implements a new method in Model

  • Model#backUpAddressbook(Path) — Saves a copy of the address book into the path in a XML format.

Current implementation of Listing of backup snapshots

Listing of the snapshots of backups is done with the RestoreSnapshotsCommand class. It also extends the Command class.

BackupList

The BackupList object holds a map of files with indexes as its keys. It also has an array of String. The position of the strings corresponds to the index of the file it represents in the map.

  • BackupList#getFileName() — returns a list of the names of the snapshots.

  • BackupList#getFileMap() — returns a map of the snapshots, each denoted with an INDEX

  • BackupList#millisToDateAndTime(String fileName) — converts a timestamp in milliseconds to a formatted date and time format.

Current implementation of Restoring from the list

The restoration of backup snapshots is done in the RestoreCommand class. It extends the Command class with an overriding execute function.

Model

This feature implements a new method in Model

  • Model#replaceData(Path path) — Overrides the current address book information with another XML file.

Usage Scenarios

Given below is the sequence of actions done by the address book when you back up and restore your data.

Saving a Backup

Step 1. The user executes backup to create a backup snapshot

Step 2. The user input is first parsed by AddressBookParser which creates a new BackupCommand object.

Step 3. BackupCommand is executed and calls Model#backUpAddressbook(Path) with the path of the .backup folder as the argument. This creates a copy of the address book data in the folder as an XML file.

Step 4. An AddressBookStorage will be created in the Model#backUpAddressbook(Path) method which facilitates the saving of the data of address book.

Step 5. saveAddressBook() will be called to save the data of the address book.

AddressBookStorage will check if the .backup folder exists. If not it will create the folder.

The following sequence diagrams shows you how the add operation works:

backupSequenceDiagramLogic

Figure 1. Interactions inside the Logic component for the backup command.

backupSequenceDiagramStorage

Figure 2. Interactions inside the Storage component for the backup command.

Listing all the snapshots

Step 1. The user executes restore-snapshots to get a list of all backup snapshots

Step 2. The user input is first parsed by AddressBookParser which creates a new RestoreSnapshotsCommand object.

Step 3. RestoreSnapshotsCommand is executed and calls readBackupList(String) with the directory of the .backup folder as the argument. This reads a BackupList from the given destination path. A list of formatted file names will be created which will be shown to the user.

The following sequence diagrams shows you how the add operation works:

restoreSnapshotsSequenceDiagramLogic

Figure 3. Interactions inside the Logic component for the restore-snapshots command.

Restoring from a backup

Step 1. The user executes restore 1 to restore their data with a backup snapshot denoted by an index of 1

Step 2. The user input is first parsed by AddressBookParser which creates a new RestoreCommandParser object.

Step 3. The argument, 1, is then parsed by RestoreCommandParser.

Step 4. RestoreCommandParser checks the validity of the index as input by the user. It then creates a BackupList object.

If the index is not valid, an error would be returned to the user instead of creating a RestoreCommand object.

Step 5. RestoreCommandParser then creates a new RestoreCommand with the BackupList and index as its arguments.

Step 6. RestoreCommand is executed and calls Model#replaceData(Path) which replaces the data of the address book with the XML file denoted by the Path.

Before calling Model#replaceData(Path path), the address book is checked if it is encrypted with a password, via FileEncryptor. It the address book is locked, an error would be displayed to the user instead of carrying on with the command.

Step 7. A XmlAddressBookStorage will be initialised which helps to read the data of the XML file.

Step 8. The address book will be overwritten with the new data by calling resetData with the new data as its argument.

restoreSequenceDiagramLogic

Figure 4. Interactions inside the Logic component for the restore 1 command.

restoreSequenceDiagramStorage

Figure 5. Interactions inside the Storage component for the restore 1 command.

Export and Import

Current implementation of Export

The export function is facilitated by the ExportCommand class. It extends the Command class wit an overriding execute function.

CsvWriter

CsvWriter is an object that takes in a path of where the export is to be saved and write a CSV file into the said path.
The conversion is as follows:
Step 1. The constructor converts an ObservableList<Person> into a List<Person> Step 2. The convertToCsv() method will be called in ExportCommand and a new CSV file will be written with the content of the created List<Person>.
Step 3. This file will be created in the path.

Current implementation of Import

The import function is implemented with the ImportCommand class. It extends the Command class with an overriding execute method.

CsvReader

CsvReader is an object that takes in a CSV file and converts it into a list of persons.
The conversion is as follows:
Step 1. The constructor reads a CSV file line by line.
Step 2. The convertToList method formats the file into a Model friendly format.
Step 3. It then converts the strings into a persons.
Step 4. These persons are then stored in a List<Person> and returned.

Usage Scenarios

Given below is the sequence of actions done by the address book when you export and import an address book.

Exporting your address book

Step 1. The user executes export d/C:\Users\USER\Desktop\DemoExport f/test to export their data to the directory with the file name the user wants.

Step 2. The user input is first parsed by AddressBookParser which creates a new ExportCommandParser object.

Step 3. The argument, d/C:\Users\USER\Desktop\DemoExport f/test, is then parsed by ExportCommandParser.

Step 4. ExportCommandParser checks the validity of the directory as input by the user. It then creates a ExportCommand object with the directory and file name as its arguments.

If the directory is not valid or a file with the same file name exists in the directory, an error would be returned to the user instead of creating a ExportCommand object.

Step 5. ExportCommand is executed and creates a CsvWriter object. The CsvWriter object is created with a copy of the address book taken from Model

Step 6. convertToCsv(String directory) is called with the full directory as the argument which writes the data of the address book to a file of CSV format.

Before calling convertToCsv(String directory), the address book is checked if it is encrypted with a password, via FileEncryptor. It the address book is locked, an error would be displayed to the user instead of carrying on with the command.

The following sequence diagrams shows you how the add operation works:

exportSequenceDiagramLogic

Figure 1. Interactions inside the Logic component for the export d/C:\Users\USER\Desktop\DemoExport f/test command.

exportSequenceDiagramStorage

Figure 2. Interactions inside the Storage component for the export d/C:\Users\USER\Desktop\DemoExport f/test command.

Importing to your address book

Step 1. The user executes import d/C:\Users\USER\Desktop\DemoExport f/test to import their data from the directory with the name of the file.

Step 2. The user input is first parsed by AddressBookParser which creates a new ImportCommandParser object.

Step 3. The argument, d/C:\Users\USER\Desktop\DemoExport f/test, is then parsed by ImportCommandParser.

Step 4. ImportCommandParser checks the validity of the directory as input by the user. It then creates a ImportCommand object with the directory and file.

If the directory is not valid or a file with the name does not exists in the directory, an error would be returned to the user instead of creating a ImportCommand object.
If the file is of the wrong format, an error would also be returned to the user instead of creating a ImportCommand object.

Step 5. ImportCommand is executed and creates a CsvReader object. The CsvReader object is created with the file identified

Step 6. convertToList() is called which creates a list of persons that can be added.

Before calling convertToList(), the address book is checked if it is encrypted with a password, via FileEncryptor. It the address book is locked, an error would be displayed to the user instead of carrying on with the command.

Step 7. There is a loop that iterates through the list and add the persons into the address book. All duplicated persons will be skipped.

The following sequence diagrams shows you how the add operation works:

importSequenceDiagramLogic

Figure 1. Interactions inside the Logic component for the import d/C:\Users\USER\Desktop\DemoExport f/test command.