PROJECT: Infinity Machine


Overview

Infinity Machine is a desktop application used for managing and storing research data. It is targeted at tech-savvy university students who are comfortable with using the Command Line Interface. It allows the adding of sources, generating and editing bibliography for a source as well as a fail-safe mode for easy retrieving of lost data in the event that our users accidentally deleted any important research data. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has more than 10 kLoC.

Summary of contributions

Major enhancement: added a recycle bin mode

  • What it does: A recycle bin mode that allows users to safely delete from the source manager, visit, retrieve and restore all previously deleted sources. Preceding restore commands can be reversed by using the redo command.

  • Justification: This feature improves the product significantly because it prevents the loss of important data when a user accidentally deletes an important research data. Since the recycle bin has persistent storage, users will not have to be worried about losing any data as well when they leave the application or if their computer accidentally crashes. This cannot be achieved with the current undo or redo commands because it would be inefficient to revert the commands other than the delete sources if that is what the user wishes to achieve and undo is not persistent.

  • Highlights: This enhancement affects the management of deleted sources and consists of an entire new mode which is the recycle bin mode. It required an in-depth analysis of design alternatives. The implementation too was challenging because:

    • It required changes to existing commands as well as almost every component in the application.

    • It required the implementation and generation of a new json file in order to store the deleted sources for persistent storage.

  • Credits: Referenced and Analysed how AddressBook4’s json data was implemented so that it can be used to implement the persistent storage for DeletedSources.

*Minor enhancement:

  • Added a count command that allows the user to count the sources in the list retrieved from the database.

  • Updated the Undo and Redo commands to account for undoing and redoing in the recycle bin state

Code contributed

Other contributions:

Project management:

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

    • Enhancements to existing features:

  • Updated codebase to morph from AddressBook to Infinity Machine(Pull requests #106)

  • Wrote and fixed tests for existing features as well as Failing Tests and SystemTests when Refactoring (Pull requests #112)

  • Managed and kept the User Interface relevant for Infinity Machine. (Pull requests #193, #228)

Documentation:

  • Write features section of the User Guide

  • Restructured User Guide to reflect current project features

  • Write developer guide sections as well

Community:

  • PRs reviewed (with non-trivial review comments): #54, #176, #195

  • Contributed to forum discussions (examples: #28)

Tools:

  • Set-up Coveralls

{you can add/remove categories in the list above}

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.

Recycle Bin Commands

Note that Recycle Bin only support the following commands necessary to manage the deletion and restoration of a source.

Listing a deleted source : recycle-bin

Switches to Recycle Bin mode and lists all the sources deleted in Source Manager.
Format: recycle-bin

  • Switches modes from Source Manager to Recycle Bin.

  • Lists all sources previously deleted in the Source Manager.

  • Using this command in the Recycle Bin mode will list all sources deleted in the Source Manager.

Examples:

  • Test switching to Recycle Bin with deleted source:

    1. Delete 1st source in the source manager database
      delete 1

    2. use recycle-bin to switch to Recycle Bin mode
      recycle-bin

    3. Deleted source is listed.

  • Test using the command in Recycle Bin mode:

    1. Lists all deleted sources
      recycle-bin

Deleting a source : delete

Deletes the specified source permanently.
Format: delete INDEX

  • Deletes the source at the specified INDEX.

  • The index refers to the index number shown in the displayed source list.

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

  • Deleted source is added to Recycle Bin mode.

  • If source to delete is already in the Recycle Bin, it will be permanently deleted.

Examples:

  • list
    delete 2
    Deletes the 2nd source in the database.

  • search algorithms
    delete 1
    Deletes the 1st source in the results of the search command.

  • add i/Wikipedia Algorithms y/Website a/Tom Show d/Basic definitions of algorithms t/Algorithms t/Introduction
    delete 1
    add i/Wikipedia Algorithms y/Website a/Tom Show d/Basic definitions of algorithms t/Algorithms t/Introduction
    delete 1
    Permanently deletes the 1st source that is exactly the same source as the source that was previously deleted.

Restoring a source : restore

Restores the specified source from Recycle Bin back to Source Manager.
Format: restore INDEX

  • Restores the source at the specified INDEX.

  • The index refers to the index number shown in the displayed source list.

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

  • Restored source is added back to Source Manager mode.

  • If source to restore already exists in the Source Manager, an error message advising the removing of the source will be thrown.

Examples:

  • Test restoring sources:

    1. Delete 1st source in the source manager database
      delete 1

    2. use recycle-bin to switch to Recycle Bin mode
      recycle-bin

    3. restores the 2nd source in the recycle bin database.
      restore 1

  • Test restoring duplicate sources:

    1. Add a source
      add i/Wikipedia Algorithms y/Website a/Tom Show d/Basic definitions of algorithms t/Algorithms t/Introduction

    2. Delete the source
      delete 1

    3. Add the same source
      add i/Wikipedia Algorithms y/Website a/Tom Show d/Basic definitions of algorithms t/Algorithms t/Introduction

    4. Switch to Recycle Bin
      recycle-bin

    5. Restore the deleted source
      restore 1

    6. An error message is thrown advising the removing of the source since it already exists in the source manager database.

Clears the Recycle Bin : empty-bin

Clears all sources in Recycle Bin.
Format: empty-bin

  • All sources in Recycle Bin will be removed.

  • Will not clear sources in Source Manager.

Exits the Recycle Bin : exit-bin

Switches modes from Recycle Bin to Source Manager. Lists all sources in Source Manager+ Format: exit-bin

Counting total number of sources: count

Counts and returns the total number of deleted sources in the Recycle Bin.
Format: count

Examples:

  • count
    Result: Total number of source(s): 6
    Counts the total number of sources retrieved from Recycle Bin.

Undoing previous command : undo

Allows the user to reverse the last performed undoable action.
Format: undo

Undoable commands: those commands that modify the source’s content (add, delete, edit and clear).

Examples:

  • delete Algorithms
    list
    undo (reverses the delete Algorithms command)

  • select 1
    list
    undo
    The undo command fails as there are no undoable commands executed previously.

  • delete 1
    clear
    undo (reverses the clear command)
    undo (reverses the delete 1 command)

Redoing the previously undone command : redo

Allows user to redo the last performed action.
Format: redo

Examples:

  • delete 1
    undo (reverses the delete 1 command)
    redo (reapplies the delete 1 command)

  • delete 1
    redo
    The redo command fails as there are no undo commands executed previously.

  • delete 1
    empty-bin
    undo (reverses the empty-bin command)
    undo (reverses the delete 1 command)
    redo (reapplies the delete 1 command)
    redo (reapplies the empty-bin command)

Viewing help : help

Format: help

Displays the User Guide for a quick reference.

Selecting a Source : select

Format: select INDEX

Displays the source selected.

  • Selects the source at the specified INDEX.

  • The index refers to the index number shown in the displayed source list.

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

Deleting a source : delete

Deletes the specified source.
Format: delete INDEX

  • Deletes the source at the specified INDEX.

  • The index refers to the index number shown in the displayed source list.

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

  • Deleted source is added to Recycle Bin mode.

  • If source to delete is already in the Recycle Bin, it will be permanently deleted.

Examples:

  • list
    delete 2
    Deletes the 2nd source in the database.

  • search i/algorithms
    delete 1
    Deletes the 1st source in the results of the search command.

  • add i/Wikipedia Algorithms y/Website a/Tom Show d/Basic definitions of algorithms t/Algorithms t/Introduction
    delete 1
    add i/Wikipedia Algorithms y/Website a/Tom Show d/Basic definitions of algorithms t/Algorithms t/Introduction
    delete 1
    Permanently deletes the 1st source that is exactly the same source as the source that was previously deleted.

Undoing previous command : undo

Allows the user to reverse the last performed undoable action.
Format: undo

Undoable commands: those commands that modify the source’s content (add, delete, edit and clear).

Examples:

  • delete Algorithms
    list
    undo (reverses the delete Algorithms command)

  • select 1
    list
    undo
    The undo command fails as there are no undoable commands executed previously.

  • delete 1
    clear
    undo (reverses the clear command)
    undo (reverses the delete 1 command)

Redoing the previously undone command : redo

Allows user to redo the last performed action.
Format: redo

Examples:

  • delete 1
    undo (reverses the delete 1 command)
    redo (reapplies the delete 1 command)

  • delete 1
    redo
    The redo command fails as there are no undo commands executed previously.

  • delete 1
    clear
    undo (reverses the clear command)
    undo (reverses the delete 1 command)
    redo (reapplies the delete 1 command)
    redo (reapplies the clear command)

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.

Recycle Bin Mode feature

The recycle bin mode allows users to access and manage the research data that they previously deleted.

Users may do one of the following: 1. Restore a previously delete source 2. Permanently delete a source from the recycle bin 3. Clear all sources from the recycle bin 4. Undo and Redo any action in the recycle bin mode 5. Exit the recycle bin and return to the source manager mode

Overview

The restore feature is facilitated by Infinity Machine. It extends Infinity Machine with a recycle bin feature, allowing user to delete and restore source from a persistent deleted sources list. The Recycle Bin was extended from interactions with the delete command. Our rationale to create an entire mode is so that users can safely delete sources and have a place to access and retrieve them even after exiting the application accidentally or intentionally. Previously, this feature was implemented seperatedly as a restore and delete feature in the source manager however, after testing it, it proved to be very messy and confusing for our users if they did not had a mode that specifically allows them to interact with the deleted sources.

Implementation

Logic Component
  • In the Recycle bin, a RecycleBinParser was created which is a now child of SourceManagerParser in the logic component. Through the separation of different commands to different parsers, it allows us to enable or disable certain commands for Source Manager mode or Recycle Bin mode which helps to increase the usability of our application.

  • A listener has also been added in the LogicManager so that operations regarding the Recycle Bin can be detected accordingly.

Model Component
  • In the Model Component, a ParserMode enum class was added which consists of two different modes RECYCLE_BIN and SOURCE_MANAGER.

  • A DeletedSources class which implements a ReadonlyDeletedSources class and is extended by VersionedDeletedSources is created. This class contains operations that allow commands to interact with the model such as adding a deleted source to deletedsources.json data folder, deleting a source from the json file mentioned and committing any changes to the DeletedSources state to name a few.

  • The file path for the deletedsource.json data file was also added to the UserPrefs class in order to save the file path of the recycle bin database.

Storage Component
  • A JsonDeletedSourcesStorage class was created so that Recycle Bin operations can interact with the deletedsources.json data storage. It consists of reading and writing operations implemented to manage the adding, updating and removing of json data.

  • A JsonSerializableDeletedSources is also created as is it necessary in assisting the generation of sources structured in Json data format.

Operation

RecycleBinSequenceDiagram

This sequence diagram shows what happens when a source is deleted pertaining to the recycle bin.

Given below is an example usage scenario and how the recycle bin mode behaves at each step when a user deletes and restores a source.

Step 1. The user launches the application for the first time. The Infinity Machine will be initialized with the initial source database state, by default listing all the sources in an indexed fashion, with all details and in order of their addition.

Step 2. The user executes delete 1 command and only one entry, the first one, is deleted.

Step 3. The user executes recycle-bin command and the Infinity Machine switches from the Source Manager mode to the Recycle Bin mode. A list of sources that was previously deleted in the Recycle Bin is shown.

Step 4. The user executes restore 1 and only one entry will be deleted, which is the source recently deleted in the Source Manager mode.

Step 5. The user executes exit-bin and only switches the Source Manager mode.

restore alone, without any arguments, will result in error. See restore command for enumerating all database entries.

Design Considerations

  • Alternative 1 : Using a simple read and write class in the storage.

    • Pros: Easy to implement.

    • Cons: May have performance issues in terms of time usage as well as limited usability in terms of operations.

  • Alternative 2 (current choice): Using a full DeletedSource interaction structure

    • Pros: High usability and little to none performance issues.

    • Cons: Highly complex structure and since implementation touches on many components of the application there is a high chance of breaking other components or commands.

Additional Considerations

  • Deleting a source from the Source Manager mode that already exists in the Recycle Bin mode: Previously this issue caused a bug. When the user tried to delete a source from the Source Manager mode that already exists in the Recycle Bin mode. To guard against this, we deleted the source that the user is trying to delete from the source manager permanently if it already exists in the Recycle Bin so that it will not cause any conflicts this is one of the many solutions available and we chose it because this was the most efficient and logic solution to implement.

  • Restoring a source from the Recycle Bin mode that already exists in the Source Manager mode: We also considered this case as it may also cause conflicts and resolved it by displaying an advising error message that the source that the user is trying to restore already exists in the Source Manager. This is a better solution in this case compared to deleting it permanently as the user may want to do additional changes to this source.

Undo/Redo feature

Current Implementation

The undo/redo mechanism is facilitated by VersionedSourceManager. It extends SourceManager with an undo/redo history, stored internally as an sourceManagerStateList and currentStatePointer. Additionally, it implements the following operations:

  • VersionedSourceManager#commit() — Saves the current source manager state in its history.

  • VersionedSourceManager#undo() — Restores the previous source manager state from its history.

  • VersionedSourceManager#redo() — Restores a previously undone source manager state from its history.

These operations are exposed in the Model interface as Model#commitSourceManager(), Model#undoSourceManager() and Model#redoSourceManager() respectively.

Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.

Step 1. The user launches the application for the first time. The VersionedSourceManager will be initialized with the initial source manager state, and the currentStatePointer pointing to that single source manager state.

UndoRedoStartingStateListDiagram

Step 2. The user executes delete 5 command to delete the 5th source in the source manager. The delete command calls Model#commitSourceManager(), causing the modified state of the source manager after the delete 5 command executes to be saved in the sourceManagerStateList, and the currentStatePointer is shifted to the newly inserted source manager state.

UndoRedoNewCommand1StateListDiagram

Step 3. The user executes add i/algorithm …​ to add a new source. The add command also calls Model#commitSourceManager(), causing another modified source manager state to be saved into the sourceManagerStateList.

UndoRedoNewCommand2StateListDiagram
If a command fails its execution, it will not call Model#commitSourceManager(), so the source manager state will not be saved into the sourceManagerStateList.

Step 4. The user now decides that adding the source was a mistake, and decides to undo that action by executing the undo command. The undo command will call Model#undoSourceManager(), which will shift the currentStatePointer once to the left, pointing it to the previous source manager state, and restores the source manager to that state.

UndoRedoExecuteUndoStateListDiagram
If the currentStatePointer is at index 0, pointing to the initial source manager state, then there are no previous source manager states to restore. The undo command uses Model#canUndoSourceManager() to check if this is the case. If so, it will return an error to the user rather than attempting to perform the undo.

The following sequence diagram shows how the undo operation works:

UndoRedoSequenceDiagram

The redo command does the opposite — it calls Model#redoSourceManager(), which shifts the currentStatePointer once to the right, pointing to the previously undone state, and restores the source manager to that state.

If the currentStatePointer is at index sourceManagerStateList.size() - 1, pointing to the latest source manager state, then there are no undone source manager states to restore. The redo command uses Model#canRedoSourceManager() to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.

Step 5. The user then decides to execute the command list. Commands that do not modify the source manager, such as list, will usually not call Model#commitSourceManager(), Model#undoSourceManager() or Model#redoSourceManager(). Thus, the sourceManagerStateList remains unchanged.

UndoRedoNewCommand3StateListDiagram

Step 6. The user executes clear, which calls Model#commitSourceManager(). Since the currentStatePointer is not pointing at the end of the sourceManagerStateList, all address book states after the currentStatePointer will be purged. We designed it this way because it no longer makes sense to redo the add i/algorithm …​ command. This is the behavior that most modern desktop applications follow.

UndoRedoNewCommand4StateListDiagram

The following activity diagram summarizes what happens when a user executes a new command:

UndoRedoActivityDiagram

Design Considerations

Aspect: How undo & redo executes
  • Alternative 1 (current choice): Saves the entire source manager.

    • Pros: Easy to implement.

    • Cons: May have performance issues in terms of memory usage.

  • Alternative 2: Individual command knows how to undo/redo by itself.

    • Pros: Will use less memory (e.g. for delete, just save the source being deleted).

    • Cons: We must ensure that the implementation of each individual command are correct.

Aspect: Data structure to support the undo/redo commands
  • Alternative 1 (current choice): Use a list to store the history of source manager states.

    • Pros: Easy for new Computer Science student undergraduates to understand, who are likely to be the new incoming developers of our project.

    • Cons: Logic is duplicated twice. For example, when a new command is executed, we must remember to update both HistoryManager and VersionedSourceManager.

  • Alternative 2: Use HistoryManager for undo/redo

    • Pros: We do not need to maintain a separate list, and just reuse what is already in the codebase.

    • Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as HistoryManager now needs to do two different things.