Project: Intelli
Intelli is a desktop relationship tracker used by private investigators (PI) to manage their information and leads. The PI interacts with it using a CLI, and it has a GUI created with JavaFX and GraphStream. It is written in Java, and has about 6 kLoC.
Code contributed: [Functional code] [Test code]
Backing up: backup
Backs up the current address book to a fixed location (intelli.xml.bak
in the data
directory).
Any existing backup at the same location will be overwritten after running this command. |
End of Extract
Justification
This is a simple way of backing up the current state of the address book before the user performs a complex series of commands that may not be undoable.
Backup mechanism
The backup mechanism is facilitated by the backupAddressBook()
method added to the Storage
component, which saves the current state of the address book to a predefined backup location (intelli.xml.bak
in the data
directory). This functionality is then invoked through the backup
command, and the Command
and Logic
classes have been extended to have access to the Storage
component of the address book.
Design Considerations
Aspect: Type of command implemented
Alternative 1 (current choice): Command
Pros: Simple to implement; undo / redo mechanism does not need to know how to interact with Storage
to undo a backup.
Cons: Accidental backups may be invoked, potentially overwriting an existing backup.
Alternative 2: UndoableCommand
Pros: Possible to undo a backup; prevents accidental overwrites of an existing backup.
Cons: The undo / redo mechanism needs to be extended to be able to redo / undo backups, increasing interaction with the Storage
component.
Aspect: Location of backup file
Alternative 1 (current choice): data/intelli.xml.bak
Pros: Easy to locate for the user; file is always in a predictable location.
Cons: Accidental backups may be invoked, potentially overwriting an existing backup in the same location.
Alternative 2: Add a timestamp to the backup filename
Pros: Will not overwrite existing backups, can serve as rudimentary version control mechanism.
Cons: User may not be aware of how many backups they have created; might cause a lot of backups to exist, creating confusion.
Aspect: Interaction between Command
and StorageManager
Alternative 1 (current choice): Extend setData()
to also recieve the Storage
component
Pros: In line with existing architecture, does not introduce global state.
Cons: All invocations of setData()
have to be changed; but only one command uses StorageManager
, creating unnessasary busywork.
Alternative 2: Make StorageManager
a Singleton
Pros: Does not affect existing commands; easy for BackupCommand
to access.
Cons: Changes architecture of app, introduces more global state.
End of Extract
Clearing command history : clearHistory
Clears the command history.
Format: clearHistory
After the command history is cleared, you will not be able to undo any previous commands. |
End of Extract
Justification
If information was added that may be too sensitive to be in the address book, clearing the command history ensures that the information is permanently removed.
clearHistory
command mechanism
The clearHistory
command is implemented as a regular command that calls .clear()
methods added to CommandHistory
and UndoRedoStack
, which clears the command history and the undo/redo stack respectively.
Design Considerations
Aspect: Type of clearHistory
command
Alternative 1 (current choice): Command
Pros: History is permanently cleared.
Cons: Impossible to undo accidental clearing of history, meaning all undoable changes become permanent.
Alternative 2: UndoableCommand
Pros: Possible to undo accidental clearing of history.
Cons: Since the most likely use for clearHistory
is for it to be permanent, having it be undoable is counterintuitive to user expectations.
Aspect: Behaviour of clearHistory
command on empty history
Alternative 1 (current choice): Clear anyway and indicate success
Pros: Simple to implement, no additional cases to take care of.
Cons: May be confusing to declare an empty history cleared.
Alternative 2: Indicate that history is empty.
Pros: Clearer messages about the state of the command history.
Cons: More complex to implement, and the end result of clearing an empty history also results in a cleared history, meaning the user intention of clearing their history is fufilled regardless of which alternative is chosen.
End of Extract
Setting a tag colour: colourTag
Sets a colour of a tag to a new colour.
Format: colourTag TAG COLOUR
Example:
-
colourTag friend red
Sets the colour of the tagfriend
to red on next program start.
End of Extract
Justification
A custom tag colour that is saved reduces confusion for the user and allows them to quickly identify people with the same tag quickly, especially if the address book is large.
colorTag
command mechanism
The colourTag
command sets a tag colour for a given tag that is stored in UserPrefs
as a Map<Tag, String>
of tag-colour pairs.
Design Considerations
Aspect: Persistence mechanism for tag colours
Alternative 1 (current choice): Store in UserPrefs
as GUI settings
Pros: Tag colour settings remain the same for different data files, more consistency for user.
Cons: Storage
has to be extended to provide access to UserPrefs
for Command
, difficult to signal a tag colour change when no user data is modified.
Alternative 2: Store in XmlAddressBookStorage
as user data.
Pros: Easier to signal tag colour changes to GUI.
Cons: Tag colours will be different depending on which data file is loaded, leading to inconsistency and confusion for the user.
Aspect: Location for storing tag colours
Alternative 1 (current choice): Global tag colour mapping
Pros: No possibility of two identical tags having different colours, easy to update all instances of one tag with new colour.
Cons: More difficult to indicate a tag colour change to the GUI as no user data is visibly modified+
Alternative 2: Each tag stores its own colour.
Pros: Easier to signal tag colour changes to GUI.
Cons: Possibility of identical tag containing different colours.
End of Extract
Finding shortest relationship path between two people: relPath
Highlights the shortest relationship path between two people in Intelli in the graph display, if it exists.
Format: relPath FROM_INDEX TO_INDEX
Example:
-
relPath 1 2
Highlights the shortest path between the first and second person in Intelli, if it exists.
End of Extract
Justification
This allows PIs to find the most confident way in which two people are related in a relationship path. For example, a PI may use someone they know very well to contact someone they don’t via the least amount of people possible.
relPath
command mechanism
relPath
finds a shortest relationship path between two people that has the highest minimum confidence estimate, and highlights this path on the graph display. In other words, it prioritises relationships with a higher confidence level over those with lower confidence levels when deciding the shortest path.
To do so, a modifiied version of the standard Dijkstra’s shortest path algorithm is used, which takes into account path width (the smallest confidence estimate on the path) and selects edges that maximises the minimum width of the path. The algorithm can be briefly described as follows:
-
For all persons from the source person, set the path width to them at -Infinity.
-
Keep track of the width of the path to each person from the source.
-
At each iteration, take the person with the smallest width so far and consider its outgoing edges. Add an edge into the shortest path to this person if it will increase the minimum confidence estimate of the path.
-
When all persons are processed, all shortest paths with the highest minimum confidence estimate will be found.
Design Considerations
Aspect: Implementation of modified Dijkstra’s
Alternative 1 (current choice): Extend the current Dijkstra
algorithm in the GraphStream library.
Pros: Easy to implement since most of the algorithm is the same, easy to use with graph display.
Cons: Relies on external library for correctness, unable to guarantee correctness of external library.
Alternative 2: Implement modified Dijkstra’s from scratch.
Pros: Can ensure testablity and reliablity of own code, less reliance on external correctness.
Cons: More difficult implementation as it is from scratch, less compatability with graph display means integration between display and algorithm has to be manually written.
Aspect: Access to GraphWrapper
from RelPathCommand
Alternative 1 (current choice): Make GraphWrapper
a Singleton.
Pros: Easy to access from relPathCommand
, no need to modify all commands like if setData()
was extended.
Cons: Increases global state.
Alternative 2: Extend Command.setData()
to take in GraphWrapper
Pros: Similar to how other components are allowed to interact with commands, better consistency.
Cons: Since the graph display is a GUI component, no straightforward way to have Command
access it. Also means that every command’s setData()
has to be modified to take into account an external parameter.
End of Extract
List all related persons : listRelated
Shows a list of all persons in Intelli related to a given person.
Format: listRelated INDEX
End of Extract
Justification
This allows PIs to quickly see who is related to a specific person, and filter out extraneous information.
Other contributions
-
Added relationships to XML storage (Pull requests #106, #126 and #154)
-
Restrict range of confidence estimates from 0 to 100 and added tests (Pull request #131)
-
Created sample testing data (Pull request #134)
-
Converted GraphWrapper class to use Singleton pattern (Commit 174f9ac)
-
Set up project and CI (Commit 332bb64)
-
Contributed to forum discussions on HashSets (#12) and exceptions (#34)