Welcome to ATHENA’s Developer Guide! ATHENA (which stands for Automated Timetable Helper Encourager n’ Assistant), is a desktop daily life planner that aims to help students automate the process of organising their schedule. It is a Command Line Interface (CLI) based application that helps users figure out the best timetable after the user has input their pre-allocated time slots for work and relaxation.
This document describes the software architecture and design of ATHENA that should hopefully help you - a developer, designer, or software tester - understand the inner workings of ATHENA.
Do refer to the glossary if you encounter any unfamiliar terms used in this document.
JDK 11
installed on your computer.File
> Close Project
to close the existing project dialog first).Configure
> Project Defaults
> Project Structure
.New…
and select the directory where you have installed JDK 11
.OK
.File
> Settings
> Plugins
to re-enable it.Import Project
(or Open or Import
in newer versions of IntelliJ).build.gradle
file and select it. Click OK
. If prompted, choose to Open as Project
(not Open as File
).OK
to accept the default settings, if prompted.Athena
and try a few commands such as list
or help
.The Architecture Diagram shown above displays the high-level design of ATHENA. It is done with an N-tier architectural style, where the higher layers make use of services provided by lower layers. A quick overview of each component is shown below.
Athena
is responsible for:
The rest of the application mainly consists of these components:
Ui
: The user interface of ATHENA.Parser
: The component that parses user input and executes commands.TaskList
: The list storing all the user’s tasks.Storage
: The component that reads data from, and writes data to, the hard disk.TimeAllocator
: The component that allocates tasks without a specified time to a free time slot.Timetable
: The component to generate an output for the list command.The sections below provide more details for each component.
Ui
consists of AthenaUi
and ColorText
.AthenaUi
implements the Ui
interface and outputs messages that the user sees.ColorText
applies relevant colors to certain output messages.AthenaUi
also prints out error messages tied to CommandException
s that get thrown by Command
s in Athena
.LogicManager
requires AthenaUi
to execute user commands.Parser
class will parse the user command.Command
object is then created, which is executed by Athena
.TaskList
(e.g. Adding a task).AthenaUi
is called to print a message to the user.The following sequence diagram illustrates how the Parser
works:
The respective Command sequence diagrams are illustrated here under the Implementation section of this document.
TaskList
stores task data in Task
type objects.TaskList
is updated in Athena
.Task
object is created everytime the user uses the add command.Task
object is removed with the delete command.Storage
takes in a TaskList
object and converts it into an equivalent .csv file.Athena
creates a TaskList
from data.csv
.The TimeAllocator
allocates tasks without a specified time to a free time slot. i.e. Tasks that were added using the add command without the t/ parameter.
TimeAllocator
keeps track of 3 TaskList
s. One containing all of the user’s tasks, one containing only fixed tasks, and another containing only flexible tasks.TimeAllocator
creates Log
s and a TimeSlot
when allocating tasks.The Timetable
component is used to generate an output for the list command, when the user requests for Athena to print out the existing tasks. It groups the tasks by their dates and draws an ASCII art timetable for the user.
ListCommand
creates a Timetable
to generate an output when the user enters the list command.Timetable
uses the specified Importance
and Forecast
to filter the tasks in the TaskList
. It also stores the Forecast
for later use.Timetable
groups the tasks by their LocalDate
in a TimetableDay
.Timetable
also creates a TimetableDrawer
that is used to generate the timetable ASCII art.Timetable
and TimetableDrawer
store a TreeMap<LocalDate, TimetableDay>
to query for a TimetableDay
based on a specific LocalDate
quickly.This section describes some important details about how certain features are implemented.
When Athena is launched, it loads the tasks saved in data.csv, a comma-separated values (csv) file located in the same directory as the program JAR file. After processing a command issued by the user, Athena automatically saves the tasks into data.csv.
The storage mechanism is facilitated by Storage
. It reads and writes the Task
objects in TaskList
to data.csv
.
It implements the following operations:
Storage#saveTaskListData
- Writes the current tasks into the save file.Storage#loadTaskListData
- Loads the tasks from the save file into the application.These operations are called by Athena
, when the program is launched, and after each user command.
Given below is an example usage scenario and how the storage mechanism behaves at each step.
Step 1. The user launches the application for the first time. The TaskList
is initialized to be empty. At this time, there is no data.csv file present. So, when Storage
calls Storage#loadTaskListData
, this is detected and an empty data.csv file is created next to the jar file. Since there was no save file, the TaskList
remains empty.
Step 2. The user adds a task to the application, by executing add n/Assignment1 t/1100 D/16-09-2020 d/2 r/Today i/high a/Refer to lecture notes
. The TaskList
now contains 1 task (Assignment 1). After the command is executed, Athena
calls Storage#saveTaskListData
to automatically save the tasks in the TaskList
into the save file.
Step 3. The user closes the application. Nothing happens since the data in the TaskList
is already saved.
Step 4. The user launches the application again. The TaskList
is initialized to be empty. Storage#loadTaskListData
will read from data.csv
and add the tasks inside the file into the empty TaskList
. The TaskList
now contains the task added earlier (Assignment 1) in Step 3.
The following sequence diagram illustrates how the loading from storage operation works:
The following sequence diagram illustrates how the saving to storage operation works:
The processing of user commands is facilitated by AthenaUi
, Parser and the
Command` subclasses.
The following operations are implemented:
AthenaUi#detectInput
- Read user input from the standard input stream.Parser#parse
- Split the user’s input based on the command type and the various parameters given. The parameters can be entered in any order. A Command
object based on the type of command entered is returned.
The following table shows each command with their corresponding Command
subclass.
Command Type | Command Subclass |
---|---|
add | AddCommand |
edit | EditCommand |
list | ListCommand |
done | DoneCommand |
delete | DeleteCommand |
view | ViewCommand |
help | HelpCommand |
exit | ExitCommand |
Step 1. The user input will be read in by the AthenaUi
class. Athena
will call for Parser#parse
to parse the user input and retrieve the respective command type and parameters.
Step 2. Parser#parse
will then create a Command
object based on the user input. The Command
object is returned to Athena
.
Step 3. Athena
will call Command#execute
to execute the command.
The specific implementation of each command is explained in the following subsections.
The mechanism to add a task is facilitated by the AddCommand
class. The user is able to add a task with the add
command.
AddCommand#execute
is called and the Task
described by the user input is added to the TaskList
.
AddCommand
and TaskList
implements the following operations:
AddCommand#execute
- Adds the specified task into TaskList
and calls AthenaUi
to print a message to the output.TaskList#addTask
- Creates a task based on the given parameters and adds it into the list.The process starts with Parser#parse
parsing the user input and returns an AddCommand
object. This is described in the user command processing section.
Given below is an example usage scenario and how the task adding mechanism behaves at each step.
Step 1. The user launches the application for the first time. The TaskList
is initialized to be empty.
Step 2. The user adds a task to the application, by entering add n/Assignment1 t/1100 D/16-11-2020 d/2 r/Today i/high a/Refer to lecture notes
. Parser#parse
parses the user input, and creates an AddCommand
object. The AddCommand
object is returned to Athena
.
Step 3. Athena
calls AddCommand#execute
, which calls TaskList#addTask
to create a task based on the given parameters, and adds the task to the list. The TaskList
now contains 1 task (Assignment1).
Step 4. AthenaUi
prints a message to inform the user of whether the command has succeeded or failed.
The following sequence diagram illustrates how Step 3 of the task adding operation works:
The mechanism to edit a task is facilitated by the EditCommand
class. The user is able to edit a task with the edit
command.
EditCommand#execute
is called and the Task
described by the user input is edited in the TaskList
.
EditCommand
, TaskList
implements the following operations:
EditCommand#execute
- Edits the specified task in TaskList
and calls AthenaUi
to print a message to the output.TaskList#editTask
- Edits a task based on the given parameters and adds the updated task into the list.The process starts with Parser#parse
parsing the user input and returns an EditCommand
object. This is described in the user command processing section.
Given below is an example usage scenario and how the task editing mechanism behaves at each step.
Step 1. The user launches the application. The TaskList
contains at least one Task
.
Step 2. The user edits a task to the application, by inputting edit 1 t/1200
. Parser#parse
parses the user input, and creates an EditCommand
object. The EditCommand
object is returned to Athena
.
Step 3. Athena
calls EditCommand#execute
, which calls TaskList#editTask
to edit the specified task based on the given parameters. The TaskList
now has the start time of task with index 1 changed from “1100” to “1200”.
Step 4. AthenaUi
prints a message to inform the user of whether the command has succeeded or failed.
The following sequence diagram illustrates how Step 3 of the editing task operation works:
The mechanism to print out the user’s tasks is facilitated by the ListCommand
class. The user is able to see a list of their tasks with the list
command, and can provide filters to display the tasks based on their Importance
and Time
.
ListCommand#execute
is called, and a Timetable
is used to group the user’s tasks by their dates before printing them out.
ListCommand
and Timetable
implements the following operations:
ListCommand#execute
- Passes the given filters to Timetable
.Timetable#populateTimetable
- Groups the tasks by their dates in a TimetableDay
.Timetable#toString
- Prepares a string with a ASCII art timetable and a list of the user’s tasks, so that it can be printed to the user.The process starts with Parser#parse
parsing the user input and returning a ListCommand
object. This is described in the user command processing section.
Given below is an example usage scenario and how this mechanism behaves at each step.
Step 1. The user launches the application. The TaskList
contains the Task
s for the week.
Step 2. The user wants to see the HIGH
IMPORTANCE
tasks within one week from now, by entering list i/HIGH f/WEEK
. Parser#parse
parses the user input, and creates a ListCommand
object. The ListCommand
object is returned to Athena
.
Step 3. Athena
calls ListCommand#execute
, which creates a Timetable
with the TaskList
and the filter values provided by the user. Timetable
calls Timetable#populateTimetable
to groups
Step 4. AthenaUi
prints the output generated by Timetable#toString
.
The mechanism to mark a task as done is facilitated by the DoneCommand
class. The user can use this feature through the done
command.
DoneCommand#execute
is called and the Task
selected by the user is marked as done by the TaskList
.
DoneCommand
and TaskList
implements the following operations:
DoneCommand#execute
- Passes the task number of the corresponding task to TaskList
to mark the task as done, then calls AthenaUi
to print a message to the output.TaskList#markTaskAsDone
- Searches for the task with the given number, and marks it as done.The process starts with Parser#parse
parsing the user input and returning a DoneCommand
object. This is described in the user command processing section.
Given below is an example usage scenario and how this mechanism behaves at each step.
Step 1. The user launches the application. The TaskList
contains at least one Task
.
Step 2. The user marks Task 1 as done, by entering done 1
. Parser#parse
parses the user input, and creates a DoneCommand
object. The DoneCommand
object is returned to Athena
.
Step 3. Athena
calls DoneCommand#execute
, which calls TaskList#markTaskAsDone
to mark Task 1 as done. Task 1 is now marked as done.
Step 4. AthenaUi
prints a message to inform the user of whether the command has succeeded or failed.
The following sequence diagram illustrates how Step 3 of the marking task as done operation works:
The mechanism to delete a task is facilitated by the DeleteCommand
class. The user is able to delete a task with the delete
command.
DeleteCommand#execute
is called and the Task
selected by the user is deleted from the TaskList
.
DeleteCommand
and TaskList
implements the following operations:
DeleteCommand#execute
- Passes the task number of the corresponding task to TaskList
to delete the task, then calls AthenaUi
to print a message to the output.TaskList#deleteTask
- Searches for the task with the given task number, then deletes it.The process starts with Parser#parse
parsing the user input and returning a DeleteCommand
object. This is described in the User command processing section.
Given below is an example usage scenario and how this mechanism behaves at each step.
Step 1. The user launches the application. The TaskList
contains at least one Task
.
Step 2. The user deletes Task 1 by entering delete 1
. Parser#parse
parses the user input, and creates a DeleteCommand
object. The DeleteCommand
object is returned to Athena
.
Step 3. Athena
calls DeleteCommand#execute
, which calls TaskList#deleteTask
to delete Task 1. Task 1 is now deleted.
Step 4. AthenaUi
prints a message to inform the user of whether the command has succeeded or failed.
The following sequence diagram illustrates how Step 3 of the task deleting operation works:
The mechanism to view a task is facilitated by the ViewCommand
class. The user is able to view a task with the view
command.
ViewCommand#execute
is called and the details of the Task
selected by the user are displayed by the TaskList
.
ViewCommand
and TaskList
implement the following operations:
ViewCommand#execute
- Passes the selected task number to TaskList
of that task that is to be viewed, then calls AthenaUi
to print a message to the output.TaskList#getTaskDescription
- Searches for the task with the given number, and return the details of the task.The process starts with Parser#parse
parsing the user input and returning a ViewCommand
object. This is described in the User command processing section.
Given below is an example usage scenario and how this mechanism behaves at each step.
Step 1. The user launches the application. The TaskList
contains at least one Task
.
Step 2. The user views Task 1 by entering view 1
. Parser#parse
parses the user input, and creates a ViewCommand
object. The ViewCommand
object is returned to Athena
.
Step 3. Athena
calls ViewCommand#execute
, which calls TaskList
to view Task 1. The details of Task 1 can now be viewed.
Step 4. AthenaUi
prints a message to inform the user of whether the command has succeeded or failed.
The following sequence diagram illustrates how Step 3 of the task viewing operation works:
The time allocation mechanism is facilitated by TimeAllocator
. It allocates time slots to Task
objects in a TaskList
that are not given a fixed time slot by the user. It implements the following operations:
Implementation
TimeAllocator#runAllocate
- Creates Log
and TimeSlot
objects based on the tasks available. It also changes the startTime
of the allocated tasks.When Athena executes any command, the current Tasklist
is used to generate a TimeAllocator
object.
TimeAllocator
keeps tasklist
,fixedTaskList
and flexibleTaskList
objects.
TimeAllocator#runAllocate
creates a Log
object named dayLog and a TimeSlot
object to keep track of the current allocations for the day.
Before the allocation of Task
objects begin, an ArrayList unassignedTimeTasks
is created from flexibleTaskList
.
Fixed tasks that occur on the same day are placed into the dayLog
first.
TimeSlot#findNextSlot
continually finds the next possible locations for the Task
objects in flexibleTaskList
.
The method will iterate through all the combinations of Log
objects with the existing flexibleTaskList
until it finds one that completely takes up the time in the TimeSlot
or it returns the best possible timetable after going through all the possibilities.
The dayLog is used to assign the startTime
of the allocated Task
objects, and also removes them from unassignedTimeTasks
.
This process is repeated to fill up the time for the subsequent days.
Shown below is an example usage scenario and how the allocation mechanism behaves at each step.
Step 1. The user launches the application. The data.csv file located next to the application JAR file contains 5 tasks. These tasks are loaded into the TaskList
. 3 of them have a fixed time slot, while the other 2 are not assigned any time slot.
Step 2. The user executes any command and the allocator will run automatically.
Step 3. The application allocates a time slot for the Task
objects without a fixed time slot.
The following sequence diagram illustrates how the allocate operation works:
Step 4. The user executes list
to get an overview of the week. The user sees all 5 tasks in the printed timetable.
Given below are instructions to test the app manually.
Initial launch
cd Desktop
.Then, enter java -jar Athena.jar
.
Expected: Shows the command line interface with welcome message.
Shutdown ATHENA
Enter exit
into the terminal/command prompt while ATHENA is running.
Expected: A farewell message by ATHENA will be shown.
Adding a task to the list.
Test case: add n/Assignment1 t/1100 D/16-09-2020 d/2 r/Today i/high a/Refer to lecture notes
Expected: First task is added to the list. Details of the added task are shown.
Test case: add t/1100 D/16-09-2020
Expected: No task is added. Error details are shown.
Editing a task details while all tasks are shown.
Prerequisites: List all tasks using the list
command.
Test case: edit 1 n/new name
Expected: Name of the task with index 1 in the list is changed to new name
.
Test case: edit 1
Expected: No task is edited as there are no parameters entered. Error details are shown.
Test case: edit -1
Expected: No task is edited. Error details are shown.
Other incorrect edit commands to try: edit
, edit x
(where x is larger than the list size)
Expected: No task is edited. Error details are shown.
Listing all the tasks with or without filters.
Test case: list
Expected: All the tasks will be listed.
Test case: list i/HIGH f/TODAY
Expected: All the tasks today with high importance will be shown.
Test case: list f/TOMORROW
Expected: No task is listed. Error details is shown.
Marking a task as done while all tasks are shown.
Prerequisites: List all tasks using the list
command.
Test case: done 1
Expected: Task with index 1 is marked as done in the list. Details of the task are shown.
Test case: done -1
Expected: No task is marked as done. Error details are shown.
Other incorrect delete commands to try: done
, done x
(where x is larger than the list size)
Expected: No task is marked as done. Error details are shown.
Deleting a task while all tasks are shown.
Prerequisite: List all tasks using the list
command to see the existing tasks.
Test case: delete 0
Prerequisite: There should be at least one task in the list. If not, follow the steps in Adding a task to add a task.
Expected: Task with index 0 is deleted from the list. Details of the deleted task are shown.
Test case: delete -1
Expected: No task is deleted. Error details are shown.
Other incorrect delete commands to try: delete
, delete x
(x can be any number that doesn’t belong to a task in the list)
Expected: No task is deleted. Error details are shown.
Viewing a task details while all tasks are shown.
Prerequisites: List all tasks using the list
command.
Test case: view 1
Expected: Details of the task with index 1 in the list are shown.
Test case: view -1
Expected: No task details are shown. Error details are shown.
Other incorrect view commands to try: view
, view x
(where x is larger than the list size)
Expected: No task details are shown. Error details are shown.
Guide on the use of ATHENA.
Test case: help
Expected: A guide on how to use ATHENA will be shown.
Storage of user data (i.e. tasks).
Testing if ATHENA is able to handle corrupted data files.
Prerequisite: Open data.csv located next to Athena.jar.
Test case: Add ,aaaa
at the end of the last line.
Problem: The task on that line is corrupted.
Expected: When you launch Athena again, it will fail to start, and an error message will be given.
Test case: Remove one of the commas (,
) from the file. (If data.csv is not empty)
Problem: The task on that line is corrupted.
Expected: When you launch Athena again, it will fail to start, and an error message will be given.
Test case: Add aaaaa
at the end of the file.
Problem: An invalid task is added.
Expected: When you launch Athena again, it will fail to start, and an error message will be given.
Version | As a … | I want to … | So that I … |
---|---|---|---|
v1.0 |
forgetful student | upload my tasks for the week | remember to do them |
v1.0 |
student | mark my tasks as done | know that I have done them and can put them aside |
v1.0 |
student | get reminded to do the tasks that are due soon | will be on time |
v1.0 |
student | edit the tasks I added | update accordingly to small changes |
v1.0 |
student | delete the tasks I added | remove tasks that are not needed to do anymore |
v1.0 |
student | set my tasks according to importance | complete the more important tasks first |
v1.0 |
student | leave some notes for a task | remember about it |
v2.0 |
student | have a planner that tells me what time to rest | don’t exhaust myself |
v2.0 |
student | see an overview of the week ahead | make sure that I am staying on top of my tasks |
v2.0 |
student | view the details of a task | can ensure I am on the right track with tasks |
v2.0 |
busy student | know what tasks to work on next | don’t need to spend time planning |
11
installed.This section contains links to other relevant guides that may be of use.