Project: BoNUS

BoNUS is a desktop personal organizer application targeted at National University of Singapore (NUS) students, with Contacts, Events and Calendar being the main focus of this application. While users interact with it mainly through a Command Line Interface (CLI), BoNUS also provides a simple Graphical User Interface (GUI) for a better User Experience (UX).

This project is the result of a semester-long Software Engineering module, CS2103T, in NUS. The backend of BoNUS is written primarily in Java, while JavaFX is used for the frontend design. Being built based on Address Book (Level 4), an initiative from the SE-EDU team, the current codebase has expanded to around 10 kLoC.

Code contributed: [Functional code] [Test code]

Importing data : (i)import

From .xml format

Imports the data in an external XML file, including data from all three components: Contacts, Events and Calendar, into the current address book of BoNUS.
Format: (i)import FILEPATH

The default data format is .xml file. Without explicit parameters, the application will treat the given path as a file in .xml format. It is unnecessary to explicitly state import --xml FILEPATH, although you are allowed to do so.

  • Imports data from the location and file name specified by FILEPATH.

  • FILEPATH must end with an extension of .xml.

  • The file name in FILEPATH should not be empty, nor should it contain any prohibited characters ?!%*+:|"<>.

  • If a relative path is provided, the data will be imported from a location relative to the BoNUS installation directory.

  • Persons and events that exist in BoNUS and the specified file will not be imported.

  • Data in the specified XML file must be in the format as recognized by BoNUS.

Examples:

  • For Windows users:
    import C:\Users\John Doe\Documents\bonus.xml

  • For macOS and Linux users:
    import /Users/John Doe/Documents/bonus.xml

For Windows users, use \ as the name-separator in your FILEPATH.
For macOS and Linux users, use / instead.

Exporting data : (p)export

To .xml format

Exports the current data in the application, including data from all three components: Contacts, Events and Calendar, to an external location.
Format: (p)export FILEPATH

  • Exports data to the location and file name specified by FILEPATH.

  • FILEPATH must end with an extension of .xml.

  • The file name in FILEPATH should not be empty.

  • The file name and any non-existent folder names in FILEPATH should not contain any prohibited characters ?!%*+:|"<>.

  • If a relative path is provided, the data will be exported to a location relative to the BoNUS installation directory.

  • Existing data file at FILEPATH will be overwritten.

  • Parent directories, if specified in FILEPATH, will be created if they do not exist.

Examples:

  • For Windows users:
    export C:\Users\John Doe\Documents\bonus.xml

  • For macOS and Linux users:
    export /Users/John Doe/Documents/bonus.xml

For Windows users, use \ as the name-separator in your FILEPATH.
For macOS and Linux users, use / instead.


Justification

The support for import and export capabilities is essential to increase the user adoption of BoNUS, as these features allow users to incorporate BoNUS more seamlessly in their daily routines. Simply by providing the desired file location, users are able to import data into BoNUS, and export all data stored in the application to somewhere safe.

As for the latest BoNUS v1.5 official release, users are constrained to import data from, or export data to a BoNUS-recognized XML file. Nevertheless, more file formats will be supported in future releases to truly unleash the full potential of the application.

Import & export XML mechanism

In order to open up more possibilities to BoNUS, we have introduced the import and export commands. We are using ImportXmlCommand and ExportCommand to support importing and exporting of address book data through XML files.

In the following sections, we will focus on how these commands depend on the Storage component to retrieve external data, as well as the file path validation mechanism adopted on a high-level basis.

Implementation

External Data Access

In order to achieve their tasks, both import and export commands natively require access to the external environment, unlike other commands. Hence, these commands are designed to depend directly on the Storage component.

The dependence of Storage in import and export is achieved through the Command.setStorage(Storage) method. This method mimics the existing Command.setData(Model, CommandHistory, UndoRedoStack) method, where only commands that make use of the relevant data will override this method to gain access to the dependencies.

The following shows the implementation of Command.setStorage(Storage), which is not overridden commands other than ImportXmlCommand and ExportCommand:

public void setStorage(Storage storage) {
    // intentionally left empty
}

In ImportXmlCommand and ExportCommand, the overridden method is implemented in this way:

@Override
public void setStorage(Storage storage) {
    this.storage = storage;
}

Through this implementation, commands that depend directly on the Storage component (ie. import and export) are able to gain full access to Storage, while commands that do not rely on Storage remain weakly coupled to it. The following class diagram of the Logic component reflects the overall implementation on an architectural-level point of view:

LogicClassDiagramStorageEmphasis

Figure 4.5.1.1 : Structure of the Logic Component

File Path Validation

File paths, as required by import and export commands, are validated during the execution of the corresponding command. The following sequence diagram shows an example of how file path validation is performed prior exporting the address book data:

ExportCommandSequenceDiagram

Figure 4.5.1.2 : Sequence Diagram for Export Command

To facilitate better handling of invalid file paths and to provide appropriate feedback to the user, several exception classes, all of which are derived from the InvalidFilePathException class, have been implemented. The following shows the inheritance diagram of the above-mentioned exception classes:

CommonsComponentExceptionClassDiagram

Figure 4.5.1.3 : Structure of Exception Classes related to File Path Validation

With that, we are able to ensure that data would be exported to or imported from a truly valid file path as specified by the user, while being able to inform users on the mistakes that they have made.

Design Considerations

Aspect: Implementation of Storage dependency for ImportXmlCommand and ExportCommand
Alternative 1 (current choice): Add a new setStorage(Storage) method in Command
Pros: Provides direct access to Storage for commands that only requires it.
Cons: There is an inherent dependency on Storage for all commands, although the coupling is weak.
Alternative 2: Raise a BaseEvent in the EventsCenter through Model
Pros: Completely decouples Command from Storage.
Cons: The need for access to Storage is not a side-effect as with other commands that mutate the address book
(eg. add, delete etc.). The dependency of Storage is part of their native behaviour.


Aspect: Location for Implementation of File Path Validation
Alternative 1 (current choice): In Storage
Pros: Validation is not just done for user input file paths (ie. via import and export commands), but also for the address book file path as defined in the user’s preferences (ie. preferences.json).
Cons: Validation is performed after every execution of an UndoableCommand due to the saving of the address book.
Alternative 2: In CommandParser
Pros: Validation will not be done after every execution of an UndoableCommand unnecessarily.
Cons: File path validation may also be required for other purposes.


Other contributions

  • Added an informative feedback message to notify users what command they have undone or redone (Pull request #61)

  • Introduced the support of command aliases, or shorthand-equivalent commands (Pull request #38)

  • Assisted Project AcquaiNote in bug reporting and feature suggestions (Issues #74, #75, #76, Pull requests #77, #79)