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.
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
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
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
Examples:
-
Test switching to Recycle Bin with deleted source:
-
Delete 1st source in the source manager database
delete 1
-
use recycle-bin to switch to Recycle Bin mode
recycle-bin
-
Deleted source is listed.
-
-
Test using the command in Recycle Bin mode:
-
Lists all deleted sources
recycle-bin
-
Deleting a source : delete
Deletes the specified source permanently.
Format: delete INDEX
Examples:
-
list
delete 2
Deletes the 2nd source in the database. -
search algorithms
delete 1
Deletes the 1st source in the results of thesearch
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
Examples:
-
Test restoring sources:
-
Delete 1st source in the source manager database
delete 1
-
use recycle-bin to switch to Recycle Bin mode
recycle-bin
-
restores the 2nd source in the recycle bin database.
restore 1
-
-
Test restoring duplicate sources:
-
Add a source
add i/Wikipedia Algorithms y/Website a/Tom Show d/Basic definitions of algorithms t/Algorithms t/Introduction
-
Delete the source
delete 1
-
Add the same source
add i/Wikipedia Algorithms y/Website a/Tom Show d/Basic definitions of algorithms t/Algorithms t/Introduction
-
Switch to Recycle Bin
recycle-bin
-
Restore the deleted source
restore 1
-
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
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 ( |
Examples:
-
delete Algorithms
list
undo
(reverses thedelete Algorithms
command) -
select 1
list
undo
Theundo
command fails as there are no undoable commands executed previously. -
delete 1
clear
undo
(reverses theclear
command)
undo
(reverses thedelete 1
command)
Redoing the previously undone command : redo
Allows user to redo the last performed action.
Format: redo
Examples:
-
delete 1
undo
(reverses thedelete 1
command)
redo
(reapplies thedelete 1
command) -
delete 1
redo
Theredo
command fails as there are noundo
commands executed previously. -
delete 1
empty-bin
undo
(reverses theempty-bin
command)
undo
(reverses thedelete 1
command)
redo
(reapplies thedelete 1
command)
redo
(reapplies theempty-bin
command)
Deleting a source : delete
Deletes the specified source.
Format: delete INDEX
Examples:
-
list
delete 2
Deletes the 2nd source in the database. -
search i/algorithms
delete 1
Deletes the 1st source in the results of thesearch
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 ( |
Examples:
-
delete Algorithms
list
undo
(reverses thedelete Algorithms
command) -
select 1
list
undo
Theundo
command fails as there are no undoable commands executed previously. -
delete 1
clear
undo
(reverses theclear
command)
undo
(reverses thedelete 1
command)
Redoing the previously undone command : redo
Allows user to redo the last performed action.
Format: redo
Examples:
-
delete 1
undo
(reverses thedelete 1
command)
redo
(reapplies thedelete 1
command) -
delete 1
redo
Theredo
command fails as there are noundo
commands executed previously. -
delete 1
clear
undo
(reverses theclear
command)
undo
(reverses thedelete 1
command)
redo
(reapplies thedelete 1
command)
redo
(reapplies theclear
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 ofSourceManagerParser
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 modesRECYCLE_BIN
andSOURCE_MANAGER
. -
A
DeletedSources
class which implements aReadonlyDeletedSources
class and is extended byVersionedDeletedSources
is created. This class contains operations that allow commands to interact with the model such as adding a deleted source todeletedsources.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 thedeletedsources.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
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.
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.
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
.
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.
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:
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.
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.
The following activity diagram summarizes what happens when a user executes a new command:
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
andVersionedSourceManager
.
-
-
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.
-