PROJECT: Police Records Intelligent System (PRISM)
1. Introduction
The purpose of this portfolio is to document the specific contributions that I have made to this project. The project, with the end product being called “Police Records System” (PRS), was done over the course of one semester in National University of Singapore (NUS), under the module CS2113T, which aims to teach Software Engineering principles and Object-Oriented Programming. PRS was done by a team of 5 people including myself, and 4 other course mates.
1.1. Overview of Project
PRS is a product that was morphed from the original Addressbook Level 3, published by a Github organization called Software Engineering Education (https://github.com/se-edu/addressbook-level3). PRS is an application that is designed to aid Police Officers in their patrolling duties to make screening subjects more efficient and well documented. It also serves as a system for communication between Police Officers (POs) on patrol and the Headquarters Personnel (HQP) in cases where additional manpower resources are required for backup. PRS is currently a desktop application, designed specifically for users who are comfortable with using Command-Line Interface (CLI).
1.2. Main Features Implemented
Over the course of the project, my team and I have implemented 5 major features:
-
Password-Lock
-
Text Prediction and Correction
-
Screening History
-
Notification Messages
-
Editing and Deleting by NRIC of Subjects
2. Summary of Contributions
The purpose of this section is to allow readers to get a clearer idea of how the work was divided among the team, and the specific contributions that I have made for the project. The major feature that I was working on in the project is explained below
-
Role: Developer
2.1. Major Enhancement – Notification Messages System
-
What it does: This feature allows you as a system user to send specific messages to other users, and read unread messages that other uses may have sent to you. To read unread messages that have been sent to you, type “showunread” in the CLI. Messages will appear with the most urgent message appearing at the top.
-
Justification/Significance: This feature is highly significant in the product, as it is the pipeline that enables communication between different system users to happen. This is the feature that enables POs to request for backup when required, and for HQP to dispatch backup as required.
-
Highlights: This enhancement supports communication between users, which is something completely new in this system. This was previously not possible through the code base given to us in Addressbook Level 3. Thus, the implementation was highly challenging as rigorous thinking was required to come up with an appropriate system that allows various users to send and receive specifically from another user, as well as methods for storing the messages sent and received.
2.2. Minor Enhancement – Allows users to mark messages as read
-
This enhancement allows users to respond to the messages that are sent to them and updating the read status of those messages once action has been taken, depending on the nature of the message sent to them.
2.4. Other Contributions:
-
Enhancements to existing features:
-
Documentation:
-
Miscellaneous:
-
Edited
build.gradle
file to enable jar file generation using shadowJar
-
3. Contributions to the User Guide
The User Guide is written with the end-users as the main target audience. The sections which I contributed to the User Guide are as shown below:
3.1. 1. Introduction
The police database is for police officers (PO) and headquarter personnel(HQP). Both groups will have varying access and authorization levels to this database. POs would be able to read from the database after screening someone while on patrol and choose his course of action base on the status/threat level of subject. HQP would have the added functions of adding and removing people from the database. Refer to quick start to get started
3.2. 3.16 Check unread notifications: 'showunread' (HQP & PO)
For HQPs: Check inbox to see a list of backup requests made by POs, and are sorted based on severity first, and then time stamp. For POs: Check inbox to see who is responding to request for backup/ambulance/fire truck or to see if there are any dispatch orders
Format: 'showunread'
Examples (as a HQP):
-
'showunread'
-
Shows a list of dispatch requests (sorted by severity then timestamp) made by POs on the ground:
Examples (as a PO): * 'showunread' * Shows any backup messages by HQ or response for backup if any
3.3. 3.17 Check all notifications: 'inbox' (HQP & PO)
For HQPs: Check inbox to see a list of backup requests made by POs, and are sorted based on severity first, and then time stamp. For POs: Check inbox to see who is responding to request for backup/ambulance/fire truck or to see if there are any dispatch orders
Format: 'inbox'
Examples (as a HQP):
-
'inbox'
-
Shows a list of backup requests (sorted by severity then timestamp) made by POs on the ground:
Examples (as a PO): * 'inbox' * Shows any dispatch messages by HQ or response for backup if any
3.4. 3.18 Read message : 'read'(HQP & PO)
Updates the status of unread messages to read. Command to be used after showunread
or inbox
command
Format: 'read INDEX'
Examples: * read 1
3.5. 3.19 Clear inbox: 'clearinbox' (HQP & PO)
Clears the text file containing all the messages (both read and unread) for the user.
Format: 'clearinbox'
4. Contributions to the Developer Guide
The Developer Guide is written for developers who wish to contribute to the project or adapt it for their own use, to get a better understanding of the software. The sections below are my contributions to the Developer Guide:
4.1. Introduction
The purpose of this Developer Guide is to provide useful information to software developers who desire to contribute to the project (e.g. optimizing of code, adding test cases, etc.), including an overview of the software architecture, design as well as current implementations and intended functionality of current features. The police database is for police officers(PO) and headquarters personnel(HQP). Both groups will have varying access and authorization levels to this database. POs would be able to read from the database after screening someone while on patrol and choose his course of action base on the status/threat level of subject. HQP would have the added functions of adding and removing people from the database. Refer to quick start to get started.
4.2. Setting up
To set up the project successfully on your computer, follow the steps below.
4.2.1. Prerequisites
In order to start the setup, you are required to install the following:
-
JDK 9 or later
-
IntelliJ IDE
4.2.2. Importing the project into IntelliJ
-
Open IntelliJ (if you are not in the welcome screen, click
File
>Close Project
to close the existing project dialog first) -
Set up the correct JDK version
-
Click
Configure
>Project Defaults
>Project Structure
-
If JDK 9 is listed in the drop down, select it. If it is not, click
New…
and select the directory where you installed JDK 9 -
Click
OK
-
-
Click
Import Project
-
Locate the
build.gradle
file and select it. ClickOK
-
Click
Open as Project
-
Click
OK
to accept the default settings -
Run the
seedu.addressbook.Main
class (right-click theMain
class and clickRun Main.main()
) and try executing a few commands -
Run all the tests (right-click the
test
folder, and clickRun 'All Tests'
) and ensure that they pass -
Open the
StorageFile
file and check for any code errors-
Due to an ongoing issue with some of the newer versions of IntelliJ, code errors may be detected even if the project can be built and run successfully
-
To resolve this, place your cursor over any of the code section highlighted in red. Press ALT+ENTER, and select
Add '--add-modules=java.xml.bind' to module compiler options
-
4.3. Design
The diagram below shows a high level architecture design of the current classes that are used in the project.
4.4. Implementation
This section describes some of the more important details of certain features implemented.
4.5. 3a. "showunread" command
Current Implementation
Once system is unlocked, regardless of which user you are, you can use this command. This command lists the new/unread messages in your inbox based on the password you used to unlock the system. When messages are sent, they are stored inside a text file called "inboxMessages/'userID'", where 'userID' refers to the ID of the intended recipient. These text files store messages directed to each individual who can log in and access their personalised inbox. It also implements the following operations:
-
execute() - executes the "showunread" command itself and displays the result to the user.
-
loadMessages() - Searches the text file storing messages for the specific police officer identified by the userID and loads it into a data structure, sorting the messages according to how urgent they should be attended to (sorted first by read status, followed by priority and then the time the message was sent).
-
concatenateMsg() - Loaded messages are then concatenated in a single string as
fullPrintedMessage
and passed to the main window through CommandResult.
The following is an example usage scenario of the "showunread" command:
Step 1: The user input his password and unlocks the system.
Step 2: The user executes "showunread" command. The "showunread" command calls execute() which also calls getMessagesFor() method.
Step 3: The loadMessages() method searches message storage file for the messages directed to the respective user, if any, and they are stored into a data structure.
Step 4: The messages that are found and are stored in a TreeSet, split by its read status, message priority, timestamp, and the message itself for sorting purposes.
Step 5: The concatenateMsg() method will then append all unread messages in sorted order to a string to be passed to the CommandResult object later.
Step 6: execute() returns a CommandResult using the concatenated string as its argument.
Step 7: The CommandResult object displays to the user the number of unread messages he has, and the list of unread messages sorted according to their urgency.
4.5.1. Design Considerations
Aspect: How showunread command is implemented
-
Alternative 1 (current choice): Using a TreeSet
-
Pros: Auto-sorts by read-status, priority then timestamp
-
Cons: Difficult to implement
-
-
Alternative 2: Using a List
-
Pros: Smaller time complexity
-
Cons: Does not auto-sort
-
4.6. 3b. "inbox" command
Current Implementation Inbox command has the same implementation as the "showunread" command - except that it shows you all the messages that are in your inbox (both read and unread). This is to allow you to access the messages that you have previously marked as read.
4.7. 3c. "read" command
Current Implementation
Once the system is unlocked, you can access unread messages directed to you via the "showunread" command explained above. Once action has been taken based on what the message sent to you is about, you can mark the message as read using the "read" command. Messages displayd in "showunread" command is first stored inside a static HashMap, with the key as the message index and the message itself as the value of the HashMap. When the user wishes to mark a message as read, he will type "read 'index'", and the respective message displayed at that specific index will be marked as read and updated in the message storage file of the user. The "read" command can only be used after the "showunread" command has been used at least once successfully.
The following is an example usage scenario of the "read" command:
Step 1: User inputs his password and unlocks the system.
Step 2: User executes "showunread" OR "inbox" command. If command is successfully executed, a list of unread messages directed to the user will be displayed.
Step 3: Messages that are read from the user’s inbox will also be recorded in a static HashMap called recordNotifications
, with the message index used as the key.
Step 4: User executes "read 3" command. If 3 is a valid index (i.e. there were at least 3 unread messages that were displayed), the third message displayed will be marked as read.
Step 5: For the messages to be marked as read, the message itself is updated in the HashMap based on the index, and the message storage text file will be overwritten with the messages stored in the HashMap, effectively updating the read status of the message read.
Step 6: The CommandResult object displays to the user a message indicating that the updating of the read status was successful or not.
4.8. 3d. "clearinbox" command
Current Implementation
Once the system is unlocked, you can clear your own inbox should there be too many messages stored in it using this command. Once the command has been entered, ReadNotification object will first be generated to attempt reading from the text file storing messages in your inbox. This is to check that the file exists in the first place. If it reads from the text file successfully, a WriteNotification object will then be generated, instantiating a PrintWriter that overwrites the contents in the text file storing the messages in your inbox.
It also implements the following methods:
-
execute() - executes the "clearinbox" command and displays the result to the user.
-
readFromFile() - method from ReadNotification object that attempts to access the contents of the text file.
-
clearInbox() - method from WriteNotification object that clears the content in the text file storing the user’s messages.
-
clearInboxRecords() - clears any records of messages displayed to ensure that all traces of existing messages are also cleared.
The following is an example usage scenario of the "clearinbox" command:
Step 1: User inputs his password and unlocks the system.
Step 2: User executes "clearinbox" command. If command is successfully executed, the feedback "Inbox cleared!" will be displayed to the user.
4.10. Use case: Show unread messages
MSS
-
User opens System.
-
System prompts user to enter his password.
-
User enters password.
-
System prompts user to enter his command.
-
User requests to display unread messages in inbox.
-
System prints the number of unread messages and list of unread messages.
Use case ends.
Extensions
-
5a. There are no messages.
-
5a1. System informs user that there are no messages available.
Use case ends.
-
-
5b. There are no unread messages.
-
5b1. System informs user that there are no unread messages.
Use case ends.
-
-
5c. File containing user’s inbox messages is missing.
-
5c1. System informs user that there was an error loading messages.
Use case ends.
-
4.11. Use case: Show all messages
MSS
-
User opens System.
-
System prompts user to enter his password.
-
User enters password.
-
System prompts user to enter his command.
-
User requests to display all messages in inbox.
-
System prints the total number of messages, number of unread messages and full list of messages.
Use case ends.
Extensions
-
5a. There are no messages.
-
5a1. System informs user that there are no messages available.
Use case ends.
-
-
5b. There are no unread messages.
-
5b1. System informs user of his total number of messages, that there are 0 unread messages and the full list of messages.
Use case ends.
-
4.12. Use case: Clear Inbox
MSS
-
User opens System.
-
System prompts user to enter his password.
-
User enters password.
-
System prompts user to enter his command.
-
User enters command to clear his inbox.
-
System informs user that his inbox has been cleared.
Use case ends.
Extensions
-
5a. There are no messages.
-
5a1. System informs user that inbox has been cleared.
Use case ends.
-
-
6a. File storing user’s inbox messages cannot be found.
-
6a1. System informs user that inbox clearance has been unsuccessful and that the storage file is missing.
Use case ends.
-
4.13. Use case: Read messages
MSS
-
User opens System.
-
System prompts user to enter his password.
-
User enters password.
-
System prompts user to enter his command.
-
User enters command to
Show Unread Messages
-
System finds the text file storing user’s messages and displays a numbered list of messages that are unread.
-
User enters the message number he wishes to mark as read.
-
System updates message read status to 'read'.
Use case ends.
Extensions
-
7a. User enters an invalid index.
-
7a1. System shows an error message and informs user of the valid index range.
Use case ends.
-
-
7b. User enters an extremely large number for the index.
-
7b1. System informs user that the index entered is too large.
-
-
7c. There are no unread messages.
-
7c1. System informs user that there are no unread messages.
Use case ends.
-
-
*a. At anytime, user chooses to stop marking messages as read.
Use case ends.
5. Glossary
- Headquarters Personnel (HQP)
-
A PO with a high level of authorised access (read and write) to the information of subjects.
- ID
-
Refers to the identity of the user of the program based on the password he uses the log in. Currently, there can be 6 possible users - 1 HQP and 5 POs.
- Mainstream OS
-
Windows, Linux, Unix, OS-X
- NRIC
-
Stands for National Registration Identity Card. It is a 7-digit number preceded and succeeded by a letter. This forms a sequence of characters unique to each person and is used for identification purposes.
- Police Officer (PO)
-
A police officer that is on patrol duty. Has low level of authorised access (read only) to subject’s information.
- Police Records
-
Refers to the database of information that the system has of people, which includes their NRIC, name, address, past offences and status.
- Status
-
A status that is used to describe the engagement level of POs on duty. He can either be engaged (true) or free (false). It is also used to describe a subject, should he have a criminal record: wanted, xc (ex-convict), and clear.
- Subject
-
A person that is being screened by a PO.
- System
-
Refers to the
PRISM
Application itself (i.e. when a user exits the system, he closes the application).