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]

Enhancement Added: Backup

External behavior


Start of Extract [from: User Guide]

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.

Implementation


Start of Extract [from: Developer Guide]

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


Enhancement Added: Clear command history

External behavior


Start of Extract [from: User Guide]

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.

Implementation


Start of Extract [from: Developer Guide]

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


Enhancement Added: Custom tag colours

External behavior


Start of Extract [from: User Guide]

Setting a tag colour: colourTag

Sets a colour of a tag to a new colour.
Format: colourTag TAG COLOUR

  • Sets the colour of tag TAG to COLOUR.

  • TAG must be alphanumeric a-z, A-Z, 0-9.

  • COLOUR must be a CSS colour code.

  • Changes will only take effect on next program start.

Example:

  • colourTag friend red
    Sets the colour of the tag friend 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.

Implementation


Start of Extract [from: Developer Guide]

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

  • Highlights the shortest relationship path between two people as specified by FROM_INDEX and TO_INDEX.

  • Paths with higher minimum confidence estimates are preferred.

  • The indices refers to the index number shown in the most recent listing.

  • The indices must be positive integers 1, 2, 3, …​

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.

Implementation


Start of Extract [from: Developer Guide]

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:

  1. For all persons from the source person, set the path width to them at -Infinity.

  2. Keep track of the width of the path to each person from the source.

  3. 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.

  4. 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


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)