diff --git a/.classpath b/.classpath index 3f05f311a90b..0b0c754dc034 100644 --- a/.classpath +++ b/.classpath @@ -2,20 +2,22 @@ - + - + - + - - - + + + diff --git a/.project b/.project index 1c9339c5f927..8836db816fad 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - addressbook-level4 + Malitio Project addressbook-level4 created by Buildship. diff --git a/LICENSE b/LICENSE index 39b3478982c3..eddc9532c817 100644 --- a/LICENSE +++ b/LICENSE @@ -2,11 +2,11 @@ MIT License Copyright (c) 2016 Software Engineering Education - FOSS Resources -Permission is hereby granted, free of charge, to any person obtaining a copy +Permission is hereby granted, free of charge, to any task obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is +copies of the Software, and to permit tasks to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all diff --git a/README.md b/README.md index 249a00b3899c..d1deebe76441 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ [![Build Status](https://travis-ci.org/se-edu/addressbook-level4.svg?branch=master)](https://travis-ci.org/se-edu/addressbook-level4) [![Coverage Status](https://coveralls.io/repos/github/se-edu/addressbook-level4/badge.svg?branch=master)](https://coveralls.io/github/se-edu/addressbook-level4?branch=master) -# Address Book (Level 4) +# Malitio -
+
-* This is a desktop Address Book application. It has a GUI but most of the user interactions happen using +* This is a desktop to-do list application. It has a GUI but most of the user interactions happen using a CLI (Command Line Interface). * It is a Java sample application intended for students learning Software Engineering while using Java as the main programming language. @@ -28,7 +28,9 @@ #### Acknowledgements * Some parts of this sample application were inspired by the excellent - [Java FX tutorial](http://code.makery.ch/library/javafx-8-tutorial/) by *Marco Jakob*. + [Java FX tutorial](http://code.makery.ch/library/javafx-8-tutorial/) by *Marco Jakob*. + +* Base code by SE-EDU initiative at https://github.com/se-edu/ -#### Licence : [MIT](LICENSE) +#### License : [MIT](LICENSE) diff --git a/build.gradle b/build.gradle index 46b06c1e42ec..dc0d38ed88f5 100644 --- a/build.gradle +++ b/build.gradle @@ -74,7 +74,7 @@ allprojects { } shadowJar { - archiveName = "addressbook.jar" + archiveName = "malitio.jar" manifest { attributes "Main-Class": "seedu.address.MainApp" @@ -113,8 +113,8 @@ tasks.coveralls { onlyIf { System.env.'CI' } } -class AddressBookTest extends Test { - public AddressBookTest() { +class malitioTest extends Test { + public malitioTest() { forkEvery = 1 systemProperty 'testfx.setup.timeout', '60000' } @@ -128,7 +128,7 @@ class AddressBookTest extends Test { } } -task guiTests(type: AddressBookTest) { +task guiTests(type: malitioTest) { include 'guitests/**' jacoco { @@ -137,7 +137,7 @@ task guiTests(type: AddressBookTest) { } -task nonGuiTests(type: AddressBookTest) { +task nonGuiTests(type: malitioTest) { include 'seedu/address/**' jacoco { @@ -146,7 +146,7 @@ task nonGuiTests(type: AddressBookTest) { } // Test mode depends on whether headless task has been run -task allTests(type: AddressBookTest) { +task allTests(type: malitioTest) { jacoco { destinationFile = new File("${buildDir}/jacoco/test.exec") } diff --git a/config.json b/config.json new file mode 100644 index 000000000000..1c55516a885d --- /dev/null +++ b/config.json @@ -0,0 +1,7 @@ +{ + "appTitle" : "Malitio", + "logLevel" : "INFO", + "userPrefsFilePath" : "preferences.json", + "malitioFilePath" : "data/malitio.xml", + "malitioName" : "Malitio" +} \ No newline at end of file diff --git a/config/checkstyle/checkstyle-noframes-sorted.xsl b/config/checkstyle/checkstyle-noframes-sorted.xsl index 9c0ac3054165..441fd41839b4 100644 --- a/config/checkstyle/checkstyle-noframes-sorted.xsl +++ b/config/checkstyle/checkstyle-noframes-sorted.xsl @@ -1,144 +1,159 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

CheckStyle Audit

Designed for use with CheckStyle and Ant.
-
- - - -
- - - -
- - - - -
- - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +

CheckStyle Audit

+
+ Designed for use with + CheckStyle + and + Ant + . +
+
+ + + +
+ + + +
+ + + + +
+ + + + +

Files

- - - - - - - - +
NameErrors
+ + + + + + + - - - + + +
NameErrors
+ + + + + +
@@ -146,50 +161,64 @@ - -

File

- - - - - - - - - - - - - - -
Error DescriptionLine
- Back to top + +

+ File + +

+ + + + + + + + + + + + + + +
Error DescriptionLine
+ + + +
+ Back to top

Summary

- - - - - - - - - - - - + + +
FilesErrors
+ + + + + + + + +
FilesErrors
+ + + +
- - + + a b - +
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 3bab4e05bbae..034a7f591828 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -3,324 +3,253 @@ "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/findbugs/excludeFilter.xml b/config/findbugs/excludeFilter.xml index 03c15ae4cc81..c1aeab75429c 100644 --- a/config/findbugs/excludeFilter.xml +++ b/config/findbugs/excludeFilter.xml @@ -1,12 +1,12 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 33df65bea583..92cfd8913bf1 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -4,49 +4,34 @@ We are a team based in the [School of Computing, National University of Singapor ## Project Team -#### [Damith C. Rajapakse](http://www.comp.nus.edu.sg/~damithch)
-
-**Role**: Project Advisor +####[Annabel Eng Jing Wen](http://github.com/annabeleng)
+
+**Role**: Team Leader
+Responsibilities: Documentation ----- -#### [Joshua Lee](http://github.com/lejolly) -
+#### [Nathan Kwon](https://github.com/kwonn) +
Role: Developer
-Responsibilities: UI +Responsibilities: Integration ----- -#### [Leow Yijin](http://github.com/yijinl) -
+#### [Desmond Khoo](http://github.com/DesmondKhoo) +
Role: Developer
-Responsibilities: Data +Responsibilities: Code Testing ----- -#### [Martin Choo](http://github.com/m133225) -
+#### [Ng Huan Ran](https://github.com/shusiner) +
Role: Developer
-Responsibilities: Dev Ops +Responsibilities: Code Quality ------ - -#### [Thien Nguyen](https://github.com/ndt93) - Role: Developer
- Responsibilities: Threading - - ----- - -#### [You Liang](http://github.com/yl-coder) -
- Role: Developer
- Responsibilities: UI - ----- # Contributors We welcome contributions. See [Contact Us](ContactUs.md) page for more info. - -* [Akshay Narayan](https://github.com/se-edu/addressbook-level4/pulls?q=is%3Apr+author%3Aokkhoy) -* [Sam Yong](https://github.com/se-edu/addressbook-level4/pulls?q=is%3Apr+author%3Amauris) \ No newline at end of file diff --git a/docs/ContactUs.md b/docs/ContactUs.md index 866d0de3fddc..efd5541c4042 100644 --- a/docs/ContactUs.md +++ b/docs/ContactUs.md @@ -1,6 +1,6 @@ # Contact Us -* **Bug reports, Suggestions** : Post in our [issue tracker](https://github.com/se-edu/addressbook-level4/issues) +* **Bug reports, Suggestions** : Post in our [issue tracker](https://github.com/se-edu/malitio-level4/issues) if you noticed bugs or have suggestions on how to improve. * **Contributing** : We welcome pull requests. Follow the process described [here](https://github.com/oss-generic/process) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 690b6d386627..f13063ff32a0 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -52,7 +52,6 @@ **Problem: Eclipse reports some required libraries missing** * Reason: Required libraries may not have been downloaded during the project import. * Solution: [Run tests using Gardle](UsingGradle.md) once (to refresh the libraries). - ## Design @@ -91,7 +90,7 @@ command `delete 3`. ->Note how the `Model` simply raises a `AddressBookChangedEvent` when the Address Book data are changed, +>Note how the `Model` simply raises a `malitioChangedEvent` when the malitio data are changed, instead of asking the `Storage` to save the updates to the hard disk. The diagram below shows how the `EventsCenter` reacts to that event, which eventually results in the updates @@ -110,8 +109,8 @@ The sections below give more details of each component. **API** : [`Ui.java`](../src/main/java/seedu/address/ui/Ui.java) -The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, -`StatusBarFooter`, `BrowserPanel` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class +The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `(Task)ListPanel`, +`StatusBarFooter`, etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class and they can be loaded using the `UiPartLoader`. The `UI` component uses JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files @@ -132,7 +131,7 @@ The `UI` component, 1. `Logic` uses the `Parser` class to parse the user command. 2. This results in a `Command` object which is executed by the `LogicManager`. -3. The command execution can affect the `Model` (e.g. adding a person) and/or raise events. +3. The command execution can affect the `Model` (e.g. adding a task) and/or raise events. 4. The result of the command execution is encapsulated as a `CommandResult` object which is passed back to the `Ui`. Given below is the Sequence Diagram for interactions within the `Logic` component for the `execute("delete 1")` @@ -147,9 +146,9 @@ Given below is the Sequence Diagram for interactions within the `Logic` componen The `Model`, * stores a `UserPref` object that represents the user's preferences. -* stores the Address Book data. -* exposes a `UnmodifiableObservableList` that can be 'observed' e.g. the UI can be bound to this list - so that the UI automatically updates when the data in the list change. +* stores the malitio data. +* exposes a `UnmodifiableObservableList`, `UnmodifiableObservableList`, `UnmodifiableObservableList` that can be 'observed' e.g. the UI can be bound to this list + so that the UI automatically updates when the data in any of the list change. * does not depend on any of the other three components. ### Storage component @@ -160,11 +159,11 @@ The `Model`, The `Storage` component, * can save `UserPref` objects in json format and read it back. -* can save the Address Book data in xml format and read it back. +* can save the malitio data in xml format and read it back. ### Common classes -Classes used by multiple components are in the `seedu.addressbook.commons` package. +Classes used by multiple components are in the `seedu.malitio.commons` package. ## Implementation @@ -258,7 +257,7 @@ Here are the steps to create a new release. ### Managing Dependencies -A project often depends on third-party libraries. For example, Address Book depends on the +A project often depends on third-party libraries. For example, malitio depends on the [Jackson library](http://wiki.fasterxml.com/JacksonHome) for XML parsing. Managing these _dependencies_ can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives.
@@ -273,45 +272,63 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (un Priority | As a ... | I want to ... | So that I can... -------- | :-------- | :--------- | :----------- `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App -`* * *` | user | add a new person | -`* * *` | user | delete a person | remove entries that I no longer need -`* * *` | user | find a person by name | locate details of persons without having to go through the entire list -`* *` | user | hide [private contact details](#private-contact-detail) by default | minimize chance of someone else seeing them by accident -`*` | user with many persons in the address book | sort persons by name | locate a person easily +`* * *` | new user | view more information about a particular command | learn how to use various commands +`* * *` | user | add a new floating task | +`* * *` | user | add a new event | +`* * *` | user | add a new deadline | +`* * *` | user | delete a floating task | remove an entry that I no longer need or have completed +`* * *` | user | delete an event | remove an event that has passed or has been cancelled +`* * *` | user | delete a deadline | remove a deadline that has passed or been removed +`* * *` | user | find a(n) event/deadline/floating task by name | locate details of the event/deadline/task without having to go through the entire list +`* * *` | user | edit a(n) event/deadline/floating task | update it or correct any errors +`* * *` | user | set a(n) event/deadlines/floating task as a priority | know which one should be completed first +`* * *` | user | view all tasks | plan ahead depending on availablity +`* * *` | user | view all tasks on specified day(s) | plan ahead +`* * *` | user | undo my last action | rectify any mistakes I made +`* *` | user | be notified of upcoming events | remember important events +`* *` | user | be warned of clashing events | avoid a clash in my schedule +`* *` | advanced user | use shorter version of a commands | type a command faster +`*` | advanced user | switch between light/dark mode | Enhance visibility or save power +`*` | user | know the weather forecast on days with events | be prepared in case of wet weather -{More to be added} ## Appendix B : Use Cases -(For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise) +(For all use cases below, the **System** is `Malitio` and the **Actor** is the `User`, unless specified otherwise) -#### Use case: Delete person +#### Use case: Delete a floating task **MSS** -1. User requests to list persons -2. AddressBook shows a list of persons -3. User requests to delete a specific person in the list -4. AddressBook deletes the person
+1. User requests to delete a specific floating task in the floating task list +2. Malitio deletes the floating task
Use case ends. **Extensions** -2a. The list is empty +1a. The given index is invalid -> Use case ends +> 1a1. Malitio shows an error message
+ Use case restarts at step 1 -3a. The given index is invalid +#### Use case: Edit a floating task -> 3a1. AddressBook shows an error message
- Use case resumes at step 2 +**MSS** -{More to be added} +1. User requests to edit a specific floating task by its index and input changes +2. Malitio implement the specified edit and reflect the change to user
+Use case ends. + +**Extensions** +1a. The given index is invalid + +> 1a1. Malitio shows an error message
+ Use case restarts at step 1 ## Appendix C : Non Functional Requirements 1. Should work on any [mainstream OS](#mainstream-os) as long as it has Java `1.8.0_60` or higher installed. -2. Should be able to hold up to 1000 persons. +2. Should be able to hold up to 1000 floating tasks, events and deadlines combined. 3. Should come with automated unit tests and open source code. 4. Should favor DOS style commands over Unix-style commands. @@ -323,11 +340,18 @@ Use case ends. > Windows, Linux, Unix, OS-X -##### Private contact detail +##### Floating task -> A contact detail that is not meant to be shared with others +> A task that has no deadline ## Appendix E : Product Survey -{TODO: Add a summary of competing products} +**Desktop Reminder**
+Desktop Reminder is a desktop application and can be run in offline mode. It has an alert system which will ring at a specified time (determined by user) to alert the user of upcoming tasks. However, the drawback of this application is that it does not minimize to the system tray when user clicked on the 'X' button but instead, gets minimized as a window which will hover on top of the taskbar. + +**Google Calendar and Google Task**
+Google Calender displays the event and on the right side, Google Task shows the tasks which needs completion. This view enables user to see what task they have on which days easily. However, a drawback is that google task is rather simple and does not have a lot of features. + +**Remember The Milk**
+Remember The Milk (RTM) allows users to categorize task which is useful if users want to group related task together. However, a drawback of RTM is that it does not allow users to input specific reminders before the events (e.g. 10minutes before, 1 day before, etc) but only have a general reminder which will be through email to the task. Since there is a mobile app for this, the inability to generate mobile reminders (e.g. alarm or notification) is a potential hindrance especially to users who do not check their emails often. diff --git a/docs/LearningOutcomes.md b/docs/LearningOutcomes.md index 5ee57072a8d8..b2180e20eb50 100644 --- a/docs/LearningOutcomes.md +++ b/docs/LearningOutcomes.md @@ -29,7 +29,7 @@ facilitate communication between event creators and event consumers. ## Use API Design `[LO-ApiDesign]` -Note how components of AddressBook have well-defined APIs. For example, the API of the `Logic` component +Note how components of malitio have well-defined APIs. For example, the API of the `Logic` component is given in the [`Logic.java`](../src/main/java/seedu/address/logic/Logic.java)
@@ -41,7 +41,7 @@ is given in the [`Logic.java`](../src/main/java/seedu/address/logic/Logic.java) ## Use Assertions `[LO-Assertions]` -Note how the AddressBook app uses Java `assert`s to verify assumptions. +Note how the malitio app uses Java `assert`s to verify assumptions. **Resources** * [Programming With Assertions](http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html) - a @@ -52,13 +52,13 @@ Note how the AddressBook app uses Java `assert`s to verify assumptions. * Make sure assertions are enabled in Eclipse by forcing an assertion failure (e.g. add `assert false;` somewhere in the code and run the code to ensure the runtime reports an assertion failure). - * Add more assertions to AddressBook as you see fit. + * Add more assertions to malitio as you see fit. ------------------------------------------------------------------------------------------------------ ## Use Logging `[LO-Logging]` -Note [how the AddressBook app uses Java's `java.util.log` package to do logging](DeveloperGuide.md#logging). +Note [how the malitio app uses Java's `java.util.log` package to do logging](DeveloperGuide.md#logging). **Resources** * Tutorials @@ -71,17 +71,17 @@ Note [how the AddressBook app uses Java's `java.util.log` package to do logging] * [Base 22 Java Logging Standards and Guidelines](https://wiki.base22.com/display/btg/Java+Logging+Standards+and+Guidelines) #### Exercise: Add more logging - Add more logging to AddressBook as you see fit. + Add more logging to malitio as you see fit. ------------------------------------------------------------------------------------------------------ ## Use Defensive Coding `[LO-DefensiveCoding]` - Note how AddressBook uses the `ReadOnly*` interfaces to prevent objects being modified by clients who are not + Note how malitio uses the `ReadOnly*` interfaces to prevent objects being modified by clients who are not supposed to modify them. #### Exercise: identify more places for defensive coding - Analyze the AddressBook code/design to identify, + Analyze the malitio code/design to identify, * where defensive coding is used * where the code can be more defensive @@ -89,7 +89,7 @@ Note [how the AddressBook app uses Java's `java.util.log` package to do logging] ## Use Build Automation `[LO-BuildAutomation]` -Note [how the AddressBook app uses Gradle to automate build tasks](UsingGradle.md). +Note [how the malitio app uses Gradle to automate build tasks](UsingGradle.md). **Resources** * Tutorials @@ -108,7 +108,7 @@ Note [how the AddressBook app uses Gradle to automate build tasks](UsingGradle.m ## Use Continuous Integration `[LO-ContinuousIntegration]` -Note [how the AddressBook app uses Travis to perform Continuous Integration](UsingTravis.md). +Note [how the malitio app uses Travis to perform Continuous Integration](UsingTravis.md). **Resources** * Tutorials diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 0cf4b84f7470..060aa385f5c8 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -11,18 +11,18 @@ > Having any Java 8 version is not enough.
This app will not work with earlier versions of Java 8. -1. Download the latest `addressbook.jar` from the [releases](../../../releases) tab. -2. Copy the file to the folder you want to use as the home folder for your Address Book. +1. Download the latest `malitio.jar` from the [releases](../../../releases) tab. +2. Copy the file to the folder you want to use as the home folder for your malitio. 3. Double-click the file to start the app. The GUI should appear in a few seconds. > 4. Type the command in the command box and press Enter to execute it.
e.g. typing **`help`** and pressing Enter will open the help window. 5. Some example commands you can try: - * **`list`** : lists all contacts - * **`add`**` John Doe p/98765432 e/johnd@gmail.com a/John street, block 123, #01-01` : - adds a contact named `John Doe` to the Address Book. - * **`delete`**` 3` : deletes the 3rd contact shown in the current list + * **`list deadlines`** : lists all deadlines + * **`add`**` drink water` : + adds `drink water` to the to-do-list. + * **`delete`**` 3` : deletes the 3rd item shown in the current list * **`exit`** : exits the app 6. Refer to the [Features](#features) section below for details of each command.
@@ -40,95 +40,158 @@ Format: `help` > Help is also shown if you enter an incorrect command e.g. `abcd` -#### Adding a person: `add` -Adds a person to the address book
-Format: `add NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` +#### Adding a task: `add` +Adds a task to the to-do list
+Floating Task Format: `add TASK_NAME [t/TAG] [p/priority]`
+Deadline Format: `add TASK_NAME e/DDMMYYYY TTTT [t/TAG] [p/priority]`
+Event Format: `add TASK_NAME s/DDMMYYYY TTTT e/DDMMYYYY TTTT [t/TAG]` -> Persons can have any number of tags (including 0) Examples: -* `add John Doe p/98765432 e/johnd@gmail.com a/John street, block 123, #01-01` -* `add Betsy Crowe p/1234567 e/betsycrowe@gmail.com a/Newgate Prison t/criminal t/friend` +* `add drink water p/high` +* `add CS2103 homework s/09102016 1100 p/high` +* `add lunch with mom s/05102016 1400 e/05102016 1700 t/don’t be late` +* `time format is from 0000 to 2359` -#### Listing all persons : `list` -Shows a list of all persons in the address book.
+#### Listing tasks: `list` +Shows a list of all events/deadlines in the to-do list.
Format: `list` -#### Finding all persons containing any keyword in their name: `find` -Finds persons whose names contain any of the given keywords.
-Format: `find KEYWORD [MORE_KEYWORDS]` +#### Listing tasks: `list deadlines` +Shows a list of all deadlines in the to-do list.
+Format: `list deadlines` -> * The search is case sensitive. e.g `hans` will not match `Hans` +#### Listing tasks: `list DATE` +Shows a list of all events/deadlines in the to-do list on that date.
+Format: `list 07102016` + +#### Finding all deadlines/floating tasks/events containing any keyword in their names and tags: `find` +Finds all input entries specified by the type (deadlines/ floating tasks/ events) whose names contain any of the given keywords.
+If the type is not specified, all entries containing the keyword will be displayed.
+Format: `find KEYWORD [MORE KEYWORDS] [t/TYPE]` + +> * The search is case insensitive. > * The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans` -> * Only the name is searched. +> * Only the task name and tags are searched. > * Only full words will be matched e.g. `Han` will not match `Hans` -> * Persons matching at least one keyword will be returned (i.e. `OR` search). +> * Task matching at least one keyword will be returned (i.e. `OR` search). e.g. `Hans` will match `Hans Bo` Examples: -* `find John`
- Returns `John Doe` but not `john` -* `find Betsy Tim John`
- Returns Any person having names `Betsy`, `Tim`, or `John` +* `find lunch t\task`
+ Returns `lunch with mom in task` +* `find lunch t\deadlines`
+ Returns `lunch with mom in deadlines` +* `find lunch t\events`
+ Returns `lunch with mom in events` +* `find lunch dinner breakfast`
+ Returns Any task having names `lunch`, `dinner`, or `breakfast` + +#### Deleting a task : `delete` +Deletes the specified task from the to-do list. Irreversible.
+Format: `delete INDEX` + +> Deletes the task at the specified `INDEX`. + The index refers to the index number shown in the most recent listing.
+ The index **must be a positive integer** 1, 2, 3, ... + +Examples: +* `list`
+ `delete 2`
+ Deletes the 2nd task in the to-do list. +* `find lunch`
+ `delete 1`
+ Deletes the 1st task in the results of the `find` command. -#### Deleting a person : `delete` -Deletes the specified person from the address book. Irreversible.
+#### Deleting a task: `delete` +Deletes the specified task from the to-do list.
Format: `delete INDEX` -> Deletes the person at the specified `INDEX`. +> Deletes the task at the specified `INDEX`. The index refers to the index number shown in the most recent listing.
The index **must be a positive integer** 1, 2, 3, ... Examples: * `list`
`delete 2`
- Deletes the 2nd person in the address book. -* `find Betsy`
+ Deletes the 2nd task in the to-do list. +* `find lunch`
`delete 1`
- Deletes the 1st person in the results of the `find` command. + Deletes the 1st task in the results of the `find` or ‘ command. + +#### Edit a task : `edit` +Edits the specified task from the to-do list.
+Format: `edit INDEX [n/TASK_NAME] [s/DDMMYYYY TTTT] [e/DDMMYYYY TTTT] [t/TAG]` -#### Select a person : `select` -Selects the person identified by the index number used in the last person listing.
+> Edits the task at the specified `INDEX`. + The index refers to the index number shown in the most recent listing.
+ The index **must be a positive integer** 1, 2, 3, ... + +Examples: +* `list`
+ `edit 2 p/low`
+ Edit the 2nd task in the to-do list replacing the priority. +* `find lunch`
+ `edit 1 n/lunch with mom`
+ Edits the 1st task in the results of the `find` or ‘ command.
+ Need to put at least one field + +#### Select a task : `select` +Selects the task identified by the index number used in the last task listing.
Format: `select INDEX` -> Selects the person and loads the Google search page the person at the specified `INDEX`. +> Selects the task and loads the Google search page the task at the specified `INDEX`. The index refers to the index number shown in the most recent listing.
The index **must be a positive integer** 1, 2, 3, ... Examples: * `list`
`select 2`
- Selects the 2nd person in the address book. + Selects the 2nd task in Malitio. * `find Betsy`
`select 1`
- Selects the 1st person in the results of the `find` command. + Selects the 1st task in the results of the `find` command. #### Clearing all entries : `clear` -Clears all entries from the address book.
+Clears all entries from the to-do list.
Format: `clear` +#### Undo the most recent action: `undo` +Undo the most recent action and reverts the to-do list to previous state.
+Format: `undo` + +#### Redo the most recent undo action: `redo` +Redo the action
+Format: `redo` + #### Exiting the program : `exit` Exits the program.
Format: `exit` #### Saving the data -Address book data are saved in the hard disk automatically after any command that changes the data.
+Malitio data are saved in the hard disk automatically after any command that changes the data.
There is no need to save manually. + + ## FAQ **Q**: How do I transfer my data to another Computer?
**A**: Install the app in the other computer and overwrite the empty data file it creates with - the file that contains the data of your previous Address Book folder. + the file that contains the data of your previous malitio folder. ## Command Summary Command | Format -------- | :-------- -Add | `add NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` +Add | `add TASK_NAME [s/DDMMYYYY TTTT] [e/DDMMYY TTTT] [t/TAG]...` Clear | `clear` Delete | `delete INDEX` -Find | `find KEYWORD [MORE_KEYWORDS]` +Find | `find KEYWORD [MORE_KEYWORDS] [t/TYPE]` List | `list` Help | `help` Select | `select INDEX` +Undo | `undo` +Edit | `edit INDEX [n/TASK_NAME] [s/DDMMYYYY TTTT] [e/DDMMYYYY TTTT] [t/TAG]` + + diff --git a/docs/UsingGradle.md b/docs/UsingGradle.md index 578c5f8634c2..2efdbe01ff84 100644 --- a/docs/UsingGradle.md +++ b/docs/UsingGradle.md @@ -35,7 +35,7 @@ Gradle commands look like this: ## Creating the JAR file * **`shadowJar`**
- Creates the `addressbook.jar` file in the `build/jar` folder, _if the current file is outdated_.
+ Creates the `malitio.jar` file in the `build/jar` folder, _if the current file is outdated_.
e.g. `./gradlew shadowJar` > To force Gradle to create the JAR file even if the current one is up-to-date, you can '`clean`' first.
diff --git a/docs/diagrams/Bel's Copy - Model.png b/docs/diagrams/Bel's Copy - Model.png new file mode 100644 index 000000000000..43b0b6bede3e Binary files /dev/null and b/docs/diagrams/Bel's Copy - Model.png differ diff --git "a/docs/diagrams/Bel\342\200\231s Copy - Model.pptx" "b/docs/diagrams/Bel\342\200\231s Copy - Model.pptx" new file mode 100644 index 000000000000..ff70c6f6c27f Binary files /dev/null and "b/docs/diagrams/Bel\342\200\231s Copy - Model.pptx" differ diff --git a/docs/diagrams/Diagrams.pptx b/docs/diagrams/Diagrams.pptx index 3c28abe9c1d3..10aa949429bd 100644 Binary files a/docs/diagrams/Diagrams.pptx and b/docs/diagrams/Diagrams.pptx differ diff --git a/docs/images/AnnabelEng.jpg b/docs/images/AnnabelEng.jpg new file mode 100644 index 000000000000..46fd8d0daf4b Binary files /dev/null and b/docs/images/AnnabelEng.jpg differ diff --git a/docs/images/DamithRajapakse.jpg b/docs/images/DamithRajapakse.jpg deleted file mode 100644 index 127543883893..000000000000 Binary files a/docs/images/DamithRajapakse.jpg and /dev/null differ diff --git a/docs/images/DesmondKhoo.jpg b/docs/images/DesmondKhoo.jpg new file mode 100644 index 000000000000..3ab8509ecf65 Binary files /dev/null and b/docs/images/DesmondKhoo.jpg differ diff --git a/docs/images/JoshuaLee.jpg b/docs/images/JoshuaLee.jpg deleted file mode 100644 index 2d1d94e0cf5d..000000000000 Binary files a/docs/images/JoshuaLee.jpg and /dev/null differ diff --git a/docs/images/LeowYijin.jpg b/docs/images/LeowYijin.jpg deleted file mode 100644 index adbf62ad9406..000000000000 Binary files a/docs/images/LeowYijin.jpg and /dev/null differ diff --git a/docs/images/MartinChoo.jpg b/docs/images/MartinChoo.jpg deleted file mode 100644 index fd14fb94593a..000000000000 Binary files a/docs/images/MartinChoo.jpg and /dev/null differ diff --git a/docs/images/ModelClassDiagram.png b/docs/images/ModelClassDiagram.png index 8cdf11ec93a1..43b0b6bede3e 100644 Binary files a/docs/images/ModelClassDiagram.png and b/docs/images/ModelClassDiagram.png differ diff --git a/docs/images/NathanKwon.jpg b/docs/images/NathanKwon.jpg new file mode 100644 index 000000000000..e7d40bcc1ee6 Binary files /dev/null and b/docs/images/NathanKwon.jpg differ diff --git a/docs/images/NgHuanRan.jpg b/docs/images/NgHuanRan.jpg new file mode 100644 index 000000000000..e277b7c5b1ca Binary files /dev/null and b/docs/images/NgHuanRan.jpg differ diff --git a/docs/images/Ui.jpg b/docs/images/Ui.jpg new file mode 100644 index 000000000000..67172da3b47a Binary files /dev/null and b/docs/images/Ui.jpg differ diff --git a/docs/images/Ui.png b/docs/images/Ui.png deleted file mode 100644 index 7121a50a442a..000000000000 Binary files a/docs/images/Ui.png and /dev/null differ diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png index 459245e267af..5ecdd06d29b7 100644 Binary files a/docs/images/UiClassDiagram.png and b/docs/images/UiClassDiagram.png differ diff --git a/docs/images/YouLiang.jpg b/docs/images/YouLiang.jpg deleted file mode 100644 index 17b48a732272..000000000000 Binary files a/docs/images/YouLiang.jpg and /dev/null differ diff --git a/src/.project b/src/.project new file mode 100644 index 000000000000..ac4db64ed9a1 --- /dev/null +++ b/src/.project @@ -0,0 +1,17 @@ + + + src + Project src created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/src/.settings/org.eclipse.buildship.core.prefs b/src/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000000..97b7cc517bc2 --- /dev/null +++ b/src/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,9 @@ +connection.arguments= +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) +connection.gradle.user.home=null +connection.java.home=null +connection.jvm.arguments= +connection.project.dir= +derived.resources=.gradle,build +eclipse.preferences.version=1 +project.path=\: diff --git a/src/main/java/seedu/address/commons/events/model/AddressBookChangedEvent.java b/src/main/java/seedu/address/commons/events/model/AddressBookChangedEvent.java deleted file mode 100644 index 347a8359e0d5..000000000000 --- a/src/main/java/seedu/address/commons/events/model/AddressBookChangedEvent.java +++ /dev/null @@ -1,19 +0,0 @@ -package seedu.address.commons.events.model; - -import seedu.address.commons.events.BaseEvent; -import seedu.address.model.ReadOnlyAddressBook; - -/** Indicates the AddressBook in the model has changed*/ -public class AddressBookChangedEvent extends BaseEvent { - - public final ReadOnlyAddressBook data; - - public AddressBookChangedEvent(ReadOnlyAddressBook data){ - this.data = data; - } - - @Override - public String toString() { - return "number of persons " + data.getPersonList().size() + ", number of tags " + data.getTagList().size(); - } -} diff --git a/src/main/java/seedu/address/commons/events/ui/PersonPanelSelectionChangedEvent.java b/src/main/java/seedu/address/commons/events/ui/PersonPanelSelectionChangedEvent.java deleted file mode 100644 index 95377b326fa6..000000000000 --- a/src/main/java/seedu/address/commons/events/ui/PersonPanelSelectionChangedEvent.java +++ /dev/null @@ -1,26 +0,0 @@ -package seedu.address.commons.events.ui; - -import seedu.address.commons.events.BaseEvent; -import seedu.address.model.person.ReadOnlyPerson; - -/** - * Represents a selection change in the Person List Panel - */ -public class PersonPanelSelectionChangedEvent extends BaseEvent { - - - private final ReadOnlyPerson newSelection; - - public PersonPanelSelectionChangedEvent(ReadOnlyPerson newSelection){ - this.newSelection = newSelection; - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - - public ReadOnlyPerson getNewSelection() { - return newSelection; - } -} diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/address/logic/Logic.java deleted file mode 100644 index 4df1bc65cabb..000000000000 --- a/src/main/java/seedu/address/logic/Logic.java +++ /dev/null @@ -1,21 +0,0 @@ -package seedu.address.logic; - -import javafx.collections.ObservableList; -import seedu.address.logic.commands.CommandResult; -import seedu.address.model.person.ReadOnlyPerson; - -/** - * API of the Logic component - */ -public interface Logic { - /** - * Executes the command and returns the result. - * @param commandText The command as entered by the user. - * @return the result of the command execution. - */ - CommandResult execute(String commandText); - - /** Returns the filtered list of persons */ - ObservableList getFilteredPersonList(); - -} diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java deleted file mode 100644 index ce4dc1903cff..000000000000 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ /dev/null @@ -1,41 +0,0 @@ -package seedu.address.logic; - -import javafx.collections.ObservableList; -import seedu.address.commons.core.ComponentManager; -import seedu.address.commons.core.LogsCenter; -import seedu.address.logic.commands.Command; -import seedu.address.logic.commands.CommandResult; -import seedu.address.logic.parser.Parser; -import seedu.address.model.Model; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.storage.Storage; - -import java.util.logging.Logger; - -/** - * The main LogicManager of the app. - */ -public class LogicManager extends ComponentManager implements Logic { - private final Logger logger = LogsCenter.getLogger(LogicManager.class); - - private final Model model; - private final Parser parser; - - public LogicManager(Model model, Storage storage) { - this.model = model; - this.parser = new Parser(); - } - - @Override - public CommandResult execute(String commandText) { - logger.info("----------------[USER COMMAND][" + commandText + "]"); - Command command = parser.parseCommand(commandText); - command.setData(model); - return command.execute(); - } - - @Override - public ObservableList getFilteredPersonList() { - return model.getFilteredPersonList(); - } -} diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java deleted file mode 100644 index 2860a9ab2a85..000000000000 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ /dev/null @@ -1,60 +0,0 @@ -package seedu.address.logic.commands; - -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.person.*; -import seedu.address.model.tag.Tag; -import seedu.address.model.tag.UniqueTagList; - -import java.util.HashSet; -import java.util.Set; - -/** - * Adds a person to the address book. - */ -public class AddCommand extends Command { - - public static final String COMMAND_WORD = "add"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. " - + "Parameters: NAME p/PHONE e/EMAIL a/ADDRESS [t/TAG]...\n" - + "Example: " + COMMAND_WORD - + " John Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney"; - - public static final String MESSAGE_SUCCESS = "New person added: %1$s"; - public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book"; - - private final Person toAdd; - - /** - * Convenience constructor using raw values. - * - * @throws IllegalValueException if any of the raw values are invalid - */ - public AddCommand(String name, String phone, String email, String address, Set tags) - throws IllegalValueException { - final Set tagSet = new HashSet<>(); - for (String tagName : tags) { - tagSet.add(new Tag(tagName)); - } - this.toAdd = new Person( - new Name(name), - new Phone(phone), - new Email(email), - new Address(address), - new UniqueTagList(tagSet) - ); - } - - @Override - public CommandResult execute() { - assert model != null; - try { - model.addPerson(toAdd); - return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd)); - } catch (UniquePersonList.DuplicatePersonException e) { - return new CommandResult(MESSAGE_DUPLICATE_PERSON); - } - - } - -} diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java deleted file mode 100644 index 1bfebe8912a8..000000000000 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ /dev/null @@ -1,50 +0,0 @@ -package seedu.address.logic.commands; - -import seedu.address.commons.core.Messages; -import seedu.address.commons.core.UnmodifiableObservableList; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.model.person.UniquePersonList.PersonNotFoundException; - -/** - * Deletes a person identified using it's last displayed index from the address book. - */ -public class DeleteCommand extends Command { - - public static final String COMMAND_WORD = "delete"; - - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the person identified by the index number used in the last person listing.\n" - + "Parameters: INDEX (must be a positive integer)\n" - + "Example: " + COMMAND_WORD + " 1"; - - public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; - - public final int targetIndex; - - public DeleteCommand(int targetIndex) { - this.targetIndex = targetIndex; - } - - - @Override - public CommandResult execute() { - - UnmodifiableObservableList lastShownList = model.getFilteredPersonList(); - - if (lastShownList.size() < targetIndex) { - indicateAttemptToExecuteIncorrectCommand(); - return new CommandResult(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); - } - - ReadOnlyPerson personToDelete = lastShownList.get(targetIndex - 1); - - try { - model.deletePerson(personToDelete); - } catch (PersonNotFoundException pnfe) { - assert false : "The target person cannot be missing"; - } - - return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete)); - } - -} diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java deleted file mode 100644 index 1d61bf6cc857..000000000000 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ /dev/null @@ -1,30 +0,0 @@ -package seedu.address.logic.commands; - -import java.util.Set; - -/** - * Finds and lists all persons in address book whose name contains any of the argument keywords. - * Keyword matching is case sensitive. - */ -public class FindCommand extends Command { - - public static final String COMMAND_WORD = "find"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of " - + "the specified keywords (case-sensitive) and displays them as a list with index numbers.\n" - + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" - + "Example: " + COMMAND_WORD + " alice bob charlie"; - - private final Set keywords; - - public FindCommand(Set keywords) { - this.keywords = keywords; - } - - @Override - public CommandResult execute() { - model.updateFilteredPersonList(keywords); - return new CommandResult(getMessageForPersonListShownSummary(model.getFilteredPersonList().size())); - } - -} diff --git a/src/main/java/seedu/address/logic/commands/SelectCommand.java b/src/main/java/seedu/address/logic/commands/SelectCommand.java deleted file mode 100644 index 9ca0551f1951..000000000000 --- a/src/main/java/seedu/address/logic/commands/SelectCommand.java +++ /dev/null @@ -1,44 +0,0 @@ -package seedu.address.logic.commands; - -import seedu.address.commons.core.EventsCenter; -import seedu.address.commons.core.Messages; -import seedu.address.commons.events.ui.JumpToListRequestEvent; -import seedu.address.commons.core.UnmodifiableObservableList; -import seedu.address.model.person.ReadOnlyPerson; - -/** - * Selects a person identified using it's last displayed index from the address book. - */ -public class SelectCommand extends Command { - - public final int targetIndex; - - public static final String COMMAND_WORD = "select"; - - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Selects the person identified by the index number used in the last person listing.\n" - + "Parameters: INDEX (must be a positive integer)\n" - + "Example: " + COMMAND_WORD + " 1"; - - public static final String MESSAGE_SELECT_PERSON_SUCCESS = "Selected Person: %1$s"; - - public SelectCommand(int targetIndex) { - this.targetIndex = targetIndex; - } - - @Override - public CommandResult execute() { - - UnmodifiableObservableList lastShownList = model.getFilteredPersonList(); - - if (lastShownList.size() < targetIndex) { - indicateAttemptToExecuteIncorrectCommand(); - return new CommandResult(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); - } - - EventsCenter.getInstance().post(new JumpToListRequestEvent(targetIndex - 1)); - return new CommandResult(String.format(MESSAGE_SELECT_PERSON_SUCCESS, targetIndex)); - - } - -} diff --git a/src/main/java/seedu/address/logic/parser/Parser.java b/src/main/java/seedu/address/logic/parser/Parser.java deleted file mode 100644 index 959b2cd0383c..000000000000 --- a/src/main/java/seedu/address/logic/parser/Parser.java +++ /dev/null @@ -1,192 +0,0 @@ -package seedu.address.logic.parser; - -import seedu.address.logic.commands.*; -import seedu.address.commons.util.StringUtil; -import seedu.address.commons.exceptions.IllegalValueException; - -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; - -/** - * Parses user input. - */ -public class Parser { - - /** - * Used for initial separation of command word and args. - */ - private static final Pattern BASIC_COMMAND_FORMAT = Pattern.compile("(?\\S+)(?.*)"); - - private static final Pattern PERSON_INDEX_ARGS_FORMAT = Pattern.compile("(?.+)"); - - private static final Pattern KEYWORDS_ARGS_FORMAT = - Pattern.compile("(?\\S+(?:\\s+\\S+)*)"); // one or more keywords separated by whitespace - - private static final Pattern PERSON_DATA_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes - Pattern.compile("(?[^/]+)" - + " (?p?)p/(?[^/]+)" - + " (?p?)e/(?[^/]+)" - + " (?p?)a/(?
[^/]+)" - + "(?(?: t/[^/]+)*)"); // variable number of tags - - public Parser() {} - - /** - * Parses user input into command for execution. - * - * @param userInput full user input string - * @return the command based on the user input - */ - public Command parseCommand(String userInput) { - final Matcher matcher = BASIC_COMMAND_FORMAT.matcher(userInput.trim()); - if (!matcher.matches()) { - return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE)); - } - - final String commandWord = matcher.group("commandWord"); - final String arguments = matcher.group("arguments"); - switch (commandWord) { - - case AddCommand.COMMAND_WORD: - return prepareAdd(arguments); - - case SelectCommand.COMMAND_WORD: - return prepareSelect(arguments); - - case DeleteCommand.COMMAND_WORD: - return prepareDelete(arguments); - - case ClearCommand.COMMAND_WORD: - return new ClearCommand(); - - case FindCommand.COMMAND_WORD: - return prepareFind(arguments); - - case ListCommand.COMMAND_WORD: - return new ListCommand(); - - case ExitCommand.COMMAND_WORD: - return new ExitCommand(); - - case HelpCommand.COMMAND_WORD: - return new HelpCommand(); - - default: - return new IncorrectCommand(MESSAGE_UNKNOWN_COMMAND); - } - } - - /** - * Parses arguments in the context of the add person command. - * - * @param args full command args string - * @return the prepared command - */ - private Command prepareAdd(String args){ - final Matcher matcher = PERSON_DATA_ARGS_FORMAT.matcher(args.trim()); - // Validate arg string format - if (!matcher.matches()) { - return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); - } - try { - return new AddCommand( - matcher.group("name"), - matcher.group("phone"), - matcher.group("email"), - matcher.group("address"), - getTagsFromArgs(matcher.group("tagArguments")) - ); - } catch (IllegalValueException ive) { - return new IncorrectCommand(ive.getMessage()); - } - } - - /** - * Extracts the new person's tags from the add command's tag arguments string. - * Merges duplicate tag strings. - */ - private static Set getTagsFromArgs(String tagArguments) throws IllegalValueException { - // no tags - if (tagArguments.isEmpty()) { - return Collections.emptySet(); - } - // replace first delimiter prefix, then split - final Collection tagStrings = Arrays.asList(tagArguments.replaceFirst(" t/", "").split(" t/")); - return new HashSet<>(tagStrings); - } - - /** - * Parses arguments in the context of the delete person command. - * - * @param args full command args string - * @return the prepared command - */ - private Command prepareDelete(String args) { - - Optional index = parseIndex(args); - if(!index.isPresent()){ - return new IncorrectCommand( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); - } - - return new DeleteCommand(index.get()); - } - - /** - * Parses arguments in the context of the select person command. - * - * @param args full command args string - * @return the prepared command - */ - private Command prepareSelect(String args) { - Optional index = parseIndex(args); - if(!index.isPresent()){ - return new IncorrectCommand( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, SelectCommand.MESSAGE_USAGE)); - } - - return new SelectCommand(index.get()); - } - - /** - * Returns the specified index in the {@code command} IF a positive unsigned integer is given as the index. - * Returns an {@code Optional.empty()} otherwise. - */ - private Optional parseIndex(String command) { - final Matcher matcher = PERSON_INDEX_ARGS_FORMAT.matcher(command.trim()); - if (!matcher.matches()) { - return Optional.empty(); - } - - String index = matcher.group("targetIndex"); - if(!StringUtil.isUnsignedInteger(index)){ - return Optional.empty(); - } - return Optional.of(Integer.parseInt(index)); - - } - - /** - * Parses arguments in the context of the find person command. - * - * @param args full command args string - * @return the prepared command - */ - private Command prepareFind(String args) { - final Matcher matcher = KEYWORDS_ARGS_FORMAT.matcher(args.trim()); - if (!matcher.matches()) { - return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, - FindCommand.MESSAGE_USAGE)); - } - - // keywords delimited by whitespace - final String[] keywords = matcher.group("keywords").split("\\s+"); - final Set keywordSet = new HashSet<>(Arrays.asList(keywords)); - return new FindCommand(keywordSet); - } - -} \ No newline at end of file diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java deleted file mode 100644 index 298cc1b82ce8..000000000000 --- a/src/main/java/seedu/address/model/AddressBook.java +++ /dev/null @@ -1,163 +0,0 @@ -package seedu.address.model; - -import javafx.collections.ObservableList; -import seedu.address.model.person.Person; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.model.person.UniquePersonList; -import seedu.address.model.tag.Tag; -import seedu.address.model.tag.UniqueTagList; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * Wraps all data at the address-book level - * Duplicates are not allowed (by .equals comparison) - */ -public class AddressBook implements ReadOnlyAddressBook { - - private final UniquePersonList persons; - private final UniqueTagList tags; - - { - persons = new UniquePersonList(); - tags = new UniqueTagList(); - } - - public AddressBook() {} - - /** - * Persons and Tags are copied into this addressbook - */ - public AddressBook(ReadOnlyAddressBook toBeCopied) { - this(toBeCopied.getUniquePersonList(), toBeCopied.getUniqueTagList()); - } - - /** - * Persons and Tags are copied into this addressbook - */ - public AddressBook(UniquePersonList persons, UniqueTagList tags) { - resetData(persons.getInternalList(), tags.getInternalList()); - } - - public static ReadOnlyAddressBook getEmptyAddressBook() { - return new AddressBook(); - } - -//// list overwrite operations - - public ObservableList getPersons() { - return persons.getInternalList(); - } - - public void setPersons(List persons) { - this.persons.getInternalList().setAll(persons); - } - - public void setTags(Collection tags) { - this.tags.getInternalList().setAll(tags); - } - - public void resetData(Collection newPersons, Collection newTags) { - setPersons(newPersons.stream().map(Person::new).collect(Collectors.toList())); - setTags(newTags); - } - - public void resetData(ReadOnlyAddressBook newData) { - resetData(newData.getPersonList(), newData.getTagList()); - } - -//// person-level operations - - /** - * Adds a person to the address book. - * Also checks the new person's tags and updates {@link #tags} with any new tags found, - * and updates the Tag objects in the person to point to those in {@link #tags}. - * - * @throws UniquePersonList.DuplicatePersonException if an equivalent person already exists. - */ - public void addPerson(Person p) throws UniquePersonList.DuplicatePersonException { - syncTagsWithMasterList(p); - persons.add(p); - } - - /** - * Ensures that every tag in this person: - * - exists in the master list {@link #tags} - * - points to a Tag object in the master list - */ - private void syncTagsWithMasterList(Person person) { - final UniqueTagList personTags = person.getTags(); - tags.mergeFrom(personTags); - - // Create map with values = tag object references in the master list - final Map masterTagObjects = new HashMap<>(); - for (Tag tag : tags) { - masterTagObjects.put(tag, tag); - } - - // Rebuild the list of person tags using references from the master list - final Set commonTagReferences = new HashSet<>(); - for (Tag tag : personTags) { - commonTagReferences.add(masterTagObjects.get(tag)); - } - person.setTags(new UniqueTagList(commonTagReferences)); - } - - public boolean removePerson(ReadOnlyPerson key) throws UniquePersonList.PersonNotFoundException { - if (persons.remove(key)) { - return true; - } else { - throw new UniquePersonList.PersonNotFoundException(); - } - } - -//// tag-level operations - - public void addTag(Tag t) throws UniqueTagList.DuplicateTagException { - tags.add(t); - } - -//// util methods - - @Override - public String toString() { - return persons.getInternalList().size() + " persons, " + tags.getInternalList().size() + " tags"; - // TODO: refine later - } - - @Override - public List getPersonList() { - return Collections.unmodifiableList(persons.getInternalList()); - } - - @Override - public List getTagList() { - return Collections.unmodifiableList(tags.getInternalList()); - } - - @Override - public UniquePersonList getUniquePersonList() { - return this.persons; - } - - @Override - public UniqueTagList getUniqueTagList() { - return this.tags; - } - - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof AddressBook // instanceof handles nulls - && this.persons.equals(((AddressBook) other).persons) - && this.tags.equals(((AddressBook) other).tags)); - } - - @Override - public int hashCode() { - // use this method for custom fields hashing instead of implementing your own - return Objects.hash(persons, tags); - } -} diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java deleted file mode 100644 index d14a27a93b5e..000000000000 --- a/src/main/java/seedu/address/model/Model.java +++ /dev/null @@ -1,35 +0,0 @@ -package seedu.address.model; - -import seedu.address.commons.core.UnmodifiableObservableList; -import seedu.address.model.person.Person; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.model.person.UniquePersonList; - -import java.util.Set; - -/** - * The API of the Model component. - */ -public interface Model { - /** Clears existing backing model and replaces with the provided new data. */ - void resetData(ReadOnlyAddressBook newData); - - /** Returns the AddressBook */ - ReadOnlyAddressBook getAddressBook(); - - /** Deletes the given person. */ - void deletePerson(ReadOnlyPerson target) throws UniquePersonList.PersonNotFoundException; - - /** Adds the given person */ - void addPerson(Person person) throws UniquePersonList.DuplicatePersonException; - - /** Returns the filtered person list as an {@code UnmodifiableObservableList} */ - UnmodifiableObservableList getFilteredPersonList(); - - /** Updates the filter of the filtered person list to show all persons */ - void updateFilteredListToShowAll(); - - /** Updates the filter of the filtered person list to filter by the given keywords*/ - void updateFilteredPersonList(Set keywords); - -} diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java deleted file mode 100644 index 869226d02bf1..000000000000 --- a/src/main/java/seedu/address/model/ModelManager.java +++ /dev/null @@ -1,153 +0,0 @@ -package seedu.address.model; - -import javafx.collections.transformation.FilteredList; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.core.UnmodifiableObservableList; -import seedu.address.commons.util.StringUtil; -import seedu.address.commons.events.model.AddressBookChangedEvent; -import seedu.address.commons.core.ComponentManager; -import seedu.address.model.person.Person; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.model.person.UniquePersonList; -import seedu.address.model.person.UniquePersonList.PersonNotFoundException; - -import java.util.Set; -import java.util.logging.Logger; - -/** - * Represents the in-memory model of the address book data. - * All changes to any model should be synchronized. - */ -public class ModelManager extends ComponentManager implements Model { - private static final Logger logger = LogsCenter.getLogger(ModelManager.class); - - private final AddressBook addressBook; - private final FilteredList filteredPersons; - - /** - * Initializes a ModelManager with the given AddressBook - * AddressBook and its variables should not be null - */ - public ModelManager(AddressBook src, UserPrefs userPrefs) { - super(); - assert src != null; - assert userPrefs != null; - - logger.fine("Initializing with address book: " + src + " and user prefs " + userPrefs); - - addressBook = new AddressBook(src); - filteredPersons = new FilteredList<>(addressBook.getPersons()); - } - - public ModelManager() { - this(new AddressBook(), new UserPrefs()); - } - - public ModelManager(ReadOnlyAddressBook initialData, UserPrefs userPrefs) { - addressBook = new AddressBook(initialData); - filteredPersons = new FilteredList<>(addressBook.getPersons()); - } - - @Override - public void resetData(ReadOnlyAddressBook newData) { - addressBook.resetData(newData); - indicateAddressBookChanged(); - } - - @Override - public ReadOnlyAddressBook getAddressBook() { - return addressBook; - } - - /** Raises an event to indicate the model has changed */ - private void indicateAddressBookChanged() { - raise(new AddressBookChangedEvent(addressBook)); - } - - @Override - public synchronized void deletePerson(ReadOnlyPerson target) throws PersonNotFoundException { - addressBook.removePerson(target); - indicateAddressBookChanged(); - } - - @Override - public synchronized void addPerson(Person person) throws UniquePersonList.DuplicatePersonException { - addressBook.addPerson(person); - updateFilteredListToShowAll(); - indicateAddressBookChanged(); - } - - //=========== Filtered Person List Accessors =============================================================== - - @Override - public UnmodifiableObservableList getFilteredPersonList() { - return new UnmodifiableObservableList<>(filteredPersons); - } - - @Override - public void updateFilteredListToShowAll() { - filteredPersons.setPredicate(null); - } - - @Override - public void updateFilteredPersonList(Set keywords){ - updateFilteredPersonList(new PredicateExpression(new NameQualifier(keywords))); - } - - private void updateFilteredPersonList(Expression expression) { - filteredPersons.setPredicate(expression::satisfies); - } - - //========== Inner classes/interfaces used for filtering ================================================== - - interface Expression { - boolean satisfies(ReadOnlyPerson person); - String toString(); - } - - private class PredicateExpression implements Expression { - - private final Qualifier qualifier; - - PredicateExpression(Qualifier qualifier) { - this.qualifier = qualifier; - } - - @Override - public boolean satisfies(ReadOnlyPerson person) { - return qualifier.run(person); - } - - @Override - public String toString() { - return qualifier.toString(); - } - } - - interface Qualifier { - boolean run(ReadOnlyPerson person); - String toString(); - } - - private class NameQualifier implements Qualifier { - private Set nameKeyWords; - - NameQualifier(Set nameKeyWords) { - this.nameKeyWords = nameKeyWords; - } - - @Override - public boolean run(ReadOnlyPerson person) { - return nameKeyWords.stream() - .filter(keyword -> StringUtil.containsIgnoreCase(person.getName().fullName, keyword)) - .findAny() - .isPresent(); - } - - @Override - public String toString() { - return "name=" + String.join(", ", nameKeyWords); - } - } - -} diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java deleted file mode 100644 index bfca099b1e81..000000000000 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ /dev/null @@ -1,30 +0,0 @@ -package seedu.address.model; - - -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.model.person.UniquePersonList; -import seedu.address.model.tag.Tag; -import seedu.address.model.tag.UniqueTagList; - -import java.util.List; - -/** - * Unmodifiable view of an address book - */ -public interface ReadOnlyAddressBook { - - UniqueTagList getUniqueTagList(); - - UniquePersonList getUniquePersonList(); - - /** - * Returns an unmodifiable view of persons list - */ - List getPersonList(); - - /** - * Returns an unmodifiable view of tags list - */ - List getTagList(); - -} diff --git a/src/main/java/seedu/address/model/person/Address.java b/src/main/java/seedu/address/model/person/Address.java deleted file mode 100644 index a2bd109c005e..000000000000 --- a/src/main/java/seedu/address/model/person/Address.java +++ /dev/null @@ -1,54 +0,0 @@ -package seedu.address.model.person; - - -import seedu.address.commons.exceptions.IllegalValueException; - -/** - * Represents a Person's address in the address book. - * Guarantees: immutable; is valid as declared in {@link #isValidAddress(String)} - */ -public class Address { - - public static final String MESSAGE_ADDRESS_CONSTRAINTS = "Person addresses can be in any format"; - public static final String ADDRESS_VALIDATION_REGEX = ".+"; - - public final String value; - - /** - * Validates given address. - * - * @throws IllegalValueException if given address string is invalid. - */ - public Address(String address) throws IllegalValueException { - assert address != null; - if (!isValidAddress(address)) { - throw new IllegalValueException(MESSAGE_ADDRESS_CONSTRAINTS); - } - this.value = address; - } - - /** - * Returns true if a given string is a valid person email. - */ - public static boolean isValidAddress(String test) { - return test.matches(ADDRESS_VALIDATION_REGEX); - } - - @Override - public String toString() { - return value; - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof Address // instanceof handles nulls - && this.value.equals(((Address) other).value)); // state check - } - - @Override - public int hashCode() { - return value.hashCode(); - } - -} \ No newline at end of file diff --git a/src/main/java/seedu/address/model/person/Email.java b/src/main/java/seedu/address/model/person/Email.java deleted file mode 100644 index 5da4d1078236..000000000000 --- a/src/main/java/seedu/address/model/person/Email.java +++ /dev/null @@ -1,56 +0,0 @@ -package seedu.address.model.person; - - -import seedu.address.commons.exceptions.IllegalValueException; - -/** - * Represents a Person's phone number in the address book. - * Guarantees: immutable; is valid as declared in {@link #isValidEmail(String)} - */ -public class Email { - - public static final String MESSAGE_EMAIL_CONSTRAINTS = - "Person emails should be 2 alphanumeric/period strings separated by '@'"; - public static final String EMAIL_VALIDATION_REGEX = "[\\w\\.]+@[\\w\\.]+"; - - public final String value; - - /** - * Validates given email. - * - * @throws IllegalValueException if given email address string is invalid. - */ - public Email(String email) throws IllegalValueException { - assert email != null; - email = email.trim(); - if (!isValidEmail(email)) { - throw new IllegalValueException(MESSAGE_EMAIL_CONSTRAINTS); - } - this.value = email; - } - - /** - * Returns if a given string is a valid person email. - */ - public static boolean isValidEmail(String test) { - return test.matches(EMAIL_VALIDATION_REGEX); - } - - @Override - public String toString() { - return value; - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof Email // instanceof handles nulls - && this.value.equals(((Email) other).value)); // state check - } - - @Override - public int hashCode() { - return value.hashCode(); - } - -} diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java deleted file mode 100644 index 03ffce7d2e79..000000000000 --- a/src/main/java/seedu/address/model/person/Person.java +++ /dev/null @@ -1,90 +0,0 @@ -package seedu.address.model.person; - -import seedu.address.commons.util.CollectionUtil; -import seedu.address.model.tag.UniqueTagList; - -import java.util.Objects; - -/** - * Represents a Person in the address book. - * Guarantees: details are present and not null, field values are validated. - */ -public class Person implements ReadOnlyPerson { - - private Name name; - private Phone phone; - private Email email; - private Address address; - - private UniqueTagList tags; - - /** - * Every field must be present and not null. - */ - public Person(Name name, Phone phone, Email email, Address address, UniqueTagList tags) { - assert !CollectionUtil.isAnyNull(name, phone, email, address, tags); - this.name = name; - this.phone = phone; - this.email = email; - this.address = address; - this.tags = new UniqueTagList(tags); // protect internal tags from changes in the arg list - } - - /** - * Copy constructor. - */ - public Person(ReadOnlyPerson source) { - this(source.getName(), source.getPhone(), source.getEmail(), source.getAddress(), source.getTags()); - } - - @Override - public Name getName() { - return name; - } - - @Override - public Phone getPhone() { - return phone; - } - - @Override - public Email getEmail() { - return email; - } - - @Override - public Address getAddress() { - return address; - } - - @Override - public UniqueTagList getTags() { - return new UniqueTagList(tags); - } - - /** - * Replaces this person's tags with the tags in the argument tag list. - */ - public void setTags(UniqueTagList replacement) { - tags.setTags(replacement); - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof ReadOnlyPerson // instanceof handles nulls - && this.isSameStateAs((ReadOnlyPerson) other)); - } - - @Override - public int hashCode() { - // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, phone, email, address, tags); - } - - @Override - public String toString() { - return getAsText(); - } - -} diff --git a/src/main/java/seedu/address/model/person/Phone.java b/src/main/java/seedu/address/model/person/Phone.java deleted file mode 100644 index d27b2244b727..000000000000 --- a/src/main/java/seedu/address/model/person/Phone.java +++ /dev/null @@ -1,54 +0,0 @@ -package seedu.address.model.person; - -import seedu.address.commons.exceptions.IllegalValueException; - -/** - * Represents a Person's phone number in the address book. - * Guarantees: immutable; is valid as declared in {@link #isValidPhone(String)} - */ -public class Phone { - - public static final String MESSAGE_PHONE_CONSTRAINTS = "Person phone numbers should only contain numbers"; - public static final String PHONE_VALIDATION_REGEX = "\\d+"; - - public final String value; - - /** - * Validates given phone number. - * - * @throws IllegalValueException if given phone string is invalid. - */ - public Phone(String phone) throws IllegalValueException { - assert phone != null; - phone = phone.trim(); - if (!isValidPhone(phone)) { - throw new IllegalValueException(MESSAGE_PHONE_CONSTRAINTS); - } - this.value = phone; - } - - /** - * Returns true if a given string is a valid person phone number. - */ - public static boolean isValidPhone(String test) { - return test.matches(PHONE_VALIDATION_REGEX); - } - - @Override - public String toString() { - return value; - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof Phone // instanceof handles nulls - && this.value.equals(((Phone) other).value)); // state check - } - - @Override - public int hashCode() { - return value.hashCode(); - } - -} diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/seedu/address/model/person/UniquePersonList.java deleted file mode 100644 index 263f1fcc7dd5..000000000000 --- a/src/main/java/seedu/address/model/person/UniquePersonList.java +++ /dev/null @@ -1,98 +0,0 @@ -package seedu.address.model.person; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import seedu.address.commons.util.CollectionUtil; -import seedu.address.commons.exceptions.DuplicateDataException; - -import java.util.*; - -/** - * A list of persons that enforces uniqueness between its elements and does not allow nulls. - * - * Supports a minimal set of list operations. - * - * @see Person#equals(Object) - * @see CollectionUtil#elementsAreUnique(Collection) - */ -public class UniquePersonList implements Iterable { - - /** - * Signals that an operation would have violated the 'no duplicates' property of the list. - */ - public static class DuplicatePersonException extends DuplicateDataException { - protected DuplicatePersonException() { - super("Operation would result in duplicate persons"); - } - } - - /** - * Signals that an operation targeting a specified person in the list would fail because - * there is no such matching person in the list. - */ - public static class PersonNotFoundException extends Exception {} - - private final ObservableList internalList = FXCollections.observableArrayList(); - - /** - * Constructs empty PersonList. - */ - public UniquePersonList() {} - - /** - * Returns true if the list contains an equivalent person as the given argument. - */ - public boolean contains(ReadOnlyPerson toCheck) { - assert toCheck != null; - return internalList.contains(toCheck); - } - - /** - * Adds a person to the list. - * - * @throws DuplicatePersonException if the person to add is a duplicate of an existing person in the list. - */ - public void add(Person toAdd) throws DuplicatePersonException { - assert toAdd != null; - if (contains(toAdd)) { - throw new DuplicatePersonException(); - } - internalList.add(toAdd); - } - - /** - * Removes the equivalent person from the list. - * - * @throws PersonNotFoundException if no such person could be found in the list. - */ - public boolean remove(ReadOnlyPerson toRemove) throws PersonNotFoundException { - assert toRemove != null; - final boolean personFoundAndDeleted = internalList.remove(toRemove); - if (!personFoundAndDeleted) { - throw new PersonNotFoundException(); - } - return personFoundAndDeleted; - } - - public ObservableList getInternalList() { - return internalList; - } - - @Override - public Iterator iterator() { - return internalList.iterator(); - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof UniquePersonList // instanceof handles nulls - && this.internalList.equals( - ((UniquePersonList) other).internalList)); - } - - @Override - public int hashCode() { - return internalList.hashCode(); - } -} diff --git a/src/main/java/seedu/address/storage/AddressBookStorage.java b/src/main/java/seedu/address/storage/AddressBookStorage.java deleted file mode 100644 index 80033086985b..000000000000 --- a/src/main/java/seedu/address/storage/AddressBookStorage.java +++ /dev/null @@ -1,44 +0,0 @@ -package seedu.address.storage; - -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.model.ReadOnlyAddressBook; - -import java.io.IOException; -import java.util.Optional; - -/** - * Represents a storage for {@link seedu.address.model.AddressBook}. - */ -public interface AddressBookStorage { - - /** - * Returns the file path of the data file. - */ - String getAddressBookFilePath(); - - /** - * Returns AddressBook data as a {@link ReadOnlyAddressBook}. - * Returns {@code Optional.empty()} if storage file is not found. - * @throws DataConversionException if the data in storage is not in the expected format. - * @throws IOException if there was any problem when reading from the storage. - */ - Optional readAddressBook() throws DataConversionException, IOException; - - /** - * @see #getAddressBookFilePath() - */ - Optional readAddressBook(String filePath) throws DataConversionException, IOException; - - /** - * Saves the given {@link ReadOnlyAddressBook} to the storage. - * @param addressBook cannot be null. - * @throws IOException if there was any problem writing to the file. - */ - void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException; - - /** - * @see #saveAddressBook(ReadOnlyAddressBook) - */ - void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) throws IOException; - -} diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java deleted file mode 100644 index 91002a8a821a..000000000000 --- a/src/main/java/seedu/address/storage/Storage.java +++ /dev/null @@ -1,39 +0,0 @@ -package seedu.address.storage; - -import seedu.address.commons.events.model.AddressBookChangedEvent; -import seedu.address.commons.events.storage.DataSavingExceptionEvent; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.UserPrefs; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Optional; - -/** - * API of the Storage component - */ -public interface Storage extends AddressBookStorage, UserPrefsStorage { - - @Override - Optional readUserPrefs() throws DataConversionException, IOException; - - @Override - void saveUserPrefs(UserPrefs userPrefs) throws IOException; - - @Override - String getAddressBookFilePath(); - - @Override - Optional readAddressBook() throws DataConversionException, IOException; - - @Override - void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException; - - /** - * Saves the current version of the Address Book to the hard disk. - * Creates the data file if it is missing. - * Raises {@link DataSavingExceptionEvent} if there was an error during saving. - */ - void handleAddressBookChangedEvent(AddressBookChangedEvent abce); -} diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java deleted file mode 100644 index ba1f72f15c27..000000000000 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ /dev/null @@ -1,91 +0,0 @@ -package seedu.address.storage; - -import com.google.common.eventbus.Subscribe; -import seedu.address.commons.core.ComponentManager; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.events.model.AddressBookChangedEvent; -import seedu.address.commons.events.storage.DataSavingExceptionEvent; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.UserPrefs; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Optional; -import java.util.logging.Logger; - -/** - * Manages storage of AddressBook data in local storage. - */ -public class StorageManager extends ComponentManager implements Storage { - - private static final Logger logger = LogsCenter.getLogger(StorageManager.class); - private AddressBookStorage addressBookStorage; - private UserPrefsStorage userPrefsStorage; - - - public StorageManager(AddressBookStorage addressBookStorage, UserPrefsStorage userPrefsStorage) { - super(); - this.addressBookStorage = addressBookStorage; - this.userPrefsStorage = userPrefsStorage; - } - - public StorageManager(String addressBookFilePath, String userPrefsFilePath) { - this(new XmlAddressBookStorage(addressBookFilePath), new JsonUserPrefsStorage(userPrefsFilePath)); - } - - // ================ UserPrefs methods ============================== - - @Override - public Optional readUserPrefs() throws DataConversionException, IOException { - return userPrefsStorage.readUserPrefs(); - } - - @Override - public void saveUserPrefs(UserPrefs userPrefs) throws IOException { - userPrefsStorage.saveUserPrefs(userPrefs); - } - - - // ================ AddressBook methods ============================== - - @Override - public String getAddressBookFilePath() { - return addressBookStorage.getAddressBookFilePath(); - } - - @Override - public Optional readAddressBook() throws DataConversionException, IOException { - return readAddressBook(addressBookStorage.getAddressBookFilePath()); - } - - @Override - public Optional readAddressBook(String filePath) throws DataConversionException, IOException { - logger.fine("Attempting to read data from file: " + filePath); - return addressBookStorage.readAddressBook(filePath); - } - - @Override - public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException { - saveAddressBook(addressBook, addressBookStorage.getAddressBookFilePath()); - } - - @Override - public void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) throws IOException { - logger.fine("Attempting to write to data file: " + filePath); - addressBookStorage.saveAddressBook(addressBook, filePath); - } - - - @Override - @Subscribe - public void handleAddressBookChangedEvent(AddressBookChangedEvent event) { - logger.info(LogsCenter.getEventHandlingLogMessage(event, "Local data changed, saving to file")); - try { - saveAddressBook(event.data); - } catch (IOException e) { - raise(new DataSavingExceptionEvent(e)); - } - } - -} diff --git a/src/main/java/seedu/address/storage/XmlAdaptedPerson.java b/src/main/java/seedu/address/storage/XmlAdaptedPerson.java deleted file mode 100644 index f2167ec201b4..000000000000 --- a/src/main/java/seedu/address/storage/XmlAdaptedPerson.java +++ /dev/null @@ -1,68 +0,0 @@ -package seedu.address.storage; - -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.person.*; -import seedu.address.model.tag.Tag; -import seedu.address.model.tag.UniqueTagList; - -import javax.xml.bind.annotation.XmlElement; -import java.util.ArrayList; -import java.util.List; - -/** - * JAXB-friendly version of the Person. - */ -public class XmlAdaptedPerson { - - @XmlElement(required = true) - private String name; - @XmlElement(required = true) - private String phone; - @XmlElement(required = true) - private String email; - @XmlElement(required = true) - private String address; - - @XmlElement - private List tagged = new ArrayList<>(); - - /** - * No-arg constructor for JAXB use. - */ - public XmlAdaptedPerson() {} - - - /** - * Converts a given Person into this class for JAXB use. - * - * @param source future changes to this will not affect the created XmlAdaptedPerson - */ - public XmlAdaptedPerson(ReadOnlyPerson source) { - name = source.getName().fullName; - phone = source.getPhone().value; - email = source.getEmail().value; - address = source.getAddress().value; - tagged = new ArrayList<>(); - for (Tag tag : source.getTags()) { - tagged.add(new XmlAdaptedTag(tag)); - } - } - - /** - * Converts this jaxb-friendly adapted person object into the model's Person object. - * - * @throws IllegalValueException if there were any data constraints violated in the adapted person - */ - public Person toModelType() throws IllegalValueException { - final List personTags = new ArrayList<>(); - for (XmlAdaptedTag tag : tagged) { - personTags.add(tag.toModelType()); - } - final Name name = new Name(this.name); - final Phone phone = new Phone(this.phone); - final Email email = new Email(this.email); - final Address address = new Address(this.address); - final UniqueTagList tags = new UniqueTagList(personTags); - return new Person(name, phone, email, address, tags); - } -} diff --git a/src/main/java/seedu/address/storage/XmlAddressBookStorage.java b/src/main/java/seedu/address/storage/XmlAddressBookStorage.java deleted file mode 100644 index 30cb00270cc4..000000000000 --- a/src/main/java/seedu/address/storage/XmlAddressBookStorage.java +++ /dev/null @@ -1,73 +0,0 @@ -package seedu.address.storage; - -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.commons.util.FileUtil; -import seedu.address.model.ReadOnlyAddressBook; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Optional; -import java.util.logging.Logger; - -/** - * A class to access AddressBook data stored as an xml file on the hard disk. - */ -public class XmlAddressBookStorage implements AddressBookStorage { - - private static final Logger logger = LogsCenter.getLogger(XmlAddressBookStorage.class); - - private String filePath; - - public XmlAddressBookStorage(String filePath){ - this.filePath = filePath; - } - - public String getAddressBookFilePath(){ - return filePath; - } - - /** - * Similar to {@link #readAddressBook()} - * @param filePath location of the data. Cannot be null - * @throws DataConversionException if the file is not in the correct format. - */ - public Optional readAddressBook(String filePath) throws DataConversionException, FileNotFoundException { - assert filePath != null; - - File addressBookFile = new File(filePath); - - if (!addressBookFile.exists()) { - logger.info("AddressBook file " + addressBookFile + " not found"); - return Optional.empty(); - } - - ReadOnlyAddressBook addressBookOptional = XmlFileStorage.loadDataFromSaveFile(new File(filePath)); - - return Optional.of(addressBookOptional); - } - - /** - * Similar to {@link #saveAddressBook(ReadOnlyAddressBook)} - * @param filePath location of the data. Cannot be null - */ - public void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) throws IOException { - assert addressBook != null; - assert filePath != null; - - File file = new File(filePath); - FileUtil.createIfMissing(file); - XmlFileStorage.saveDataToFile(file, new XmlSerializableAddressBook(addressBook)); - } - - @Override - public Optional readAddressBook() throws DataConversionException, IOException { - return readAddressBook(filePath); - } - - @Override - public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException { - saveAddressBook(addressBook, filePath); - } -} diff --git a/src/main/java/seedu/address/storage/XmlSerializableAddressBook.java b/src/main/java/seedu/address/storage/XmlSerializableAddressBook.java deleted file mode 100644 index b7ec533a3a1e..000000000000 --- a/src/main/java/seedu/address/storage/XmlSerializableAddressBook.java +++ /dev/null @@ -1,88 +0,0 @@ -package seedu.address.storage; - -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.tag.Tag; -import seedu.address.model.tag.UniqueTagList; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.model.person.UniquePersonList; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -/** - * An Immutable AddressBook that is serializable to XML format - */ -@XmlRootElement(name = "addressbook") -public class XmlSerializableAddressBook implements ReadOnlyAddressBook { - - @XmlElement - private List persons; - @XmlElement - private List tags; - - { - persons = new ArrayList<>(); - tags = new ArrayList<>(); - } - - /** - * Empty constructor required for marshalling - */ - public XmlSerializableAddressBook() {} - - /** - * Conversion - */ - public XmlSerializableAddressBook(ReadOnlyAddressBook src) { - persons.addAll(src.getPersonList().stream().map(XmlAdaptedPerson::new).collect(Collectors.toList())); - tags = src.getTagList(); - } - - @Override - public UniqueTagList getUniqueTagList() { - try { - return new UniqueTagList(tags); - } catch (UniqueTagList.DuplicateTagException e) { - //TODO: better error handling - e.printStackTrace(); - return null; - } - } - - @Override - public UniquePersonList getUniquePersonList() { - UniquePersonList lists = new UniquePersonList(); - for (XmlAdaptedPerson p : persons) { - try { - lists.add(p.toModelType()); - } catch (IllegalValueException e) { - //TODO: better error handling - } - } - return lists; - } - - @Override - public List getPersonList() { - return persons.stream().map(p -> { - try { - return p.toModelType(); - } catch (IllegalValueException e) { - e.printStackTrace(); - //TODO: better error handling - return null; - } - }).collect(Collectors.toCollection(ArrayList::new)); - } - - @Override - public List getTagList() { - return Collections.unmodifiableList(tags); - } - -} diff --git a/src/main/java/seedu/address/ui/BrowserPanel.java b/src/main/java/seedu/address/ui/BrowserPanel.java deleted file mode 100644 index 54b88318019b..000000000000 --- a/src/main/java/seedu/address/ui/BrowserPanel.java +++ /dev/null @@ -1,68 +0,0 @@ -package seedu.address.ui; - -import javafx.event.Event; -import javafx.scene.Node; -import javafx.scene.layout.AnchorPane; -import javafx.scene.web.WebView; -import seedu.address.commons.util.FxViewUtil; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.commons.core.LogsCenter; - -import java.util.logging.Logger; - -/** - * The Browser Panel of the App. - */ -public class BrowserPanel extends UiPart{ - - private static Logger logger = LogsCenter.getLogger(BrowserPanel.class); - private WebView browser; - - /** - * Constructor is kept private as {@link #load(AnchorPane)} is the only way to create a BrowserPanel. - */ - private BrowserPanel() { - - } - - @Override - public void setNode(Node node) { - //not applicable - } - - @Override - public String getFxmlPath() { - return null; //not applicable - } - - /** - * Factory method for creating a Browser Panel. - * This method should be called after the FX runtime is initialized and in FX application thread. - * @param placeholder The AnchorPane where the BrowserPanel must be inserted - */ - public static BrowserPanel load(AnchorPane placeholder){ - logger.info("Initializing browser"); - BrowserPanel browserPanel = new BrowserPanel(); - browserPanel.browser = new WebView(); - placeholder.setOnKeyPressed(Event::consume); // To prevent triggering events for typing inside the loaded Web page. - FxViewUtil.applyAnchorBoundaryParameters(browserPanel.browser, 0.0, 0.0, 0.0, 0.0); - placeholder.getChildren().add(browserPanel.browser); - return browserPanel; - } - - public void loadPersonPage(ReadOnlyPerson person) { - loadPage("https://www.google.com.sg/#safe=off&q=" + person.getName().fullName.replaceAll(" ", "+")); - } - - public void loadPage(String url){ - browser.getEngine().load(url); - } - - /** - * Frees resources allocated to the browser. - */ - public void freeResources() { - browser = null; - } - -} diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java deleted file mode 100644 index 259e9ad0d333..000000000000 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ /dev/null @@ -1,65 +0,0 @@ -package seedu.address.ui; - -import javafx.fxml.FXML; -import javafx.scene.Node; -import javafx.scene.control.Label; -import javafx.scene.layout.HBox; -import seedu.address.model.person.ReadOnlyPerson; - -public class PersonCard extends UiPart{ - - private static final String FXML = "PersonListCard.fxml"; - - @FXML - private HBox cardPane; - @FXML - private Label name; - @FXML - private Label id; - @FXML - private Label phone; - @FXML - private Label address; - @FXML - private Label email; - @FXML - private Label tags; - - private ReadOnlyPerson person; - private int displayedIndex; - - public PersonCard(){ - - } - - public static PersonCard load(ReadOnlyPerson person, int displayedIndex){ - PersonCard card = new PersonCard(); - card.person = person; - card.displayedIndex = displayedIndex; - return UiPartLoader.loadUiPart(card); - } - - @FXML - public void initialize() { - name.setText(person.getName().fullName); - id.setText(displayedIndex + ". "); - phone.setText(person.getPhone().value); - address.setText(person.getAddress().value); - email.setText(person.getEmail().value); - tags.setText(person.tagsString()); - } - - public HBox getLayout() { - return cardPane; - } - - @Override - public void setNode(Node node) { - cardPane = (HBox)node; - } - - @Override - public String getFxmlPath() { - return FXML; - } -} diff --git a/src/main/java/seedu/address/ui/PersonListPanel.java b/src/main/java/seedu/address/ui/PersonListPanel.java deleted file mode 100644 index 27d9381c47b5..000000000000 --- a/src/main/java/seedu/address/ui/PersonListPanel.java +++ /dev/null @@ -1,108 +0,0 @@ -package seedu.address.ui; - -import javafx.application.Platform; -import javafx.collections.ObservableList; -import javafx.fxml.FXML; -import javafx.scene.Node; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.control.SplitPane; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.VBox; -import javafx.stage.Stage; -import seedu.address.commons.events.ui.PersonPanelSelectionChangedEvent; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.commons.core.LogsCenter; - -import java.util.logging.Logger; - -/** - * Panel containing the list of persons. - */ -public class PersonListPanel extends UiPart { - private final Logger logger = LogsCenter.getLogger(PersonListPanel.class); - private static final String FXML = "PersonListPanel.fxml"; - private VBox panel; - private AnchorPane placeHolderPane; - - @FXML - private ListView personListView; - - public PersonListPanel() { - super(); - } - - @Override - public void setNode(Node node) { - panel = (VBox) node; - } - - @Override - public String getFxmlPath() { - return FXML; - } - - @Override - public void setPlaceholder(AnchorPane pane) { - this.placeHolderPane = pane; - } - - public static PersonListPanel load(Stage primaryStage, AnchorPane personListPlaceholder, - ObservableList personList) { - PersonListPanel personListPanel = - UiPartLoader.loadUiPart(primaryStage, personListPlaceholder, new PersonListPanel()); - personListPanel.configure(personList); - return personListPanel; - } - - private void configure(ObservableList personList) { - setConnections(personList); - addToPlaceholder(); - } - - private void setConnections(ObservableList personList) { - personListView.setItems(personList); - personListView.setCellFactory(listView -> new PersonListViewCell()); - setEventHandlerForSelectionChangeEvent(); - } - - private void addToPlaceholder() { - SplitPane.setResizableWithParent(placeHolderPane, false); - placeHolderPane.getChildren().add(panel); - } - - private void setEventHandlerForSelectionChangeEvent() { - personListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { - if (newValue != null) { - logger.fine("Selection in person list panel changed to : '" + newValue + "'"); - raise(new PersonPanelSelectionChangedEvent(newValue)); - } - }); - } - - public void scrollTo(int index) { - Platform.runLater(() -> { - personListView.scrollTo(index); - personListView.getSelectionModel().clearAndSelect(index); - }); - } - - class PersonListViewCell extends ListCell { - - public PersonListViewCell() { - } - - @Override - protected void updateItem(ReadOnlyPerson person, boolean empty) { - super.updateItem(person, empty); - - if (empty || person == null) { - setGraphic(null); - setText(null); - } else { - setGraphic(PersonCard.load(person, getIndex() + 1).getLayout()); - } - } - } - -} diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/malitio/MainApp.java similarity index 75% rename from src/main/java/seedu/address/MainApp.java rename to src/main/java/seedu/malitio/MainApp.java index 36dc72a74b7a..74d329ec4dae 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/malitio/MainApp.java @@ -1,24 +1,24 @@ -package seedu.address; +package seedu.malitio; import com.google.common.eventbus.Subscribe; import javafx.application.Application; import javafx.application.Platform; import javafx.stage.Stage; -import seedu.address.commons.core.Config; -import seedu.address.commons.core.EventsCenter; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.core.Version; -import seedu.address.commons.events.ui.ExitAppRequestEvent; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.commons.util.StringUtil; -import seedu.address.logic.Logic; -import seedu.address.logic.LogicManager; -import seedu.address.model.*; -import seedu.address.commons.util.ConfigUtil; -import seedu.address.storage.Storage; -import seedu.address.storage.StorageManager; -import seedu.address.ui.Ui; -import seedu.address.ui.UiManager; +import seedu.malitio.commons.core.Config; +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.core.Version; +import seedu.malitio.commons.events.ui.ExitAppRequestEvent; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.commons.util.ConfigUtil; +import seedu.malitio.commons.util.StringUtil; +import seedu.malitio.logic.Logic; +import seedu.malitio.logic.LogicManager; +import seedu.malitio.model.*; +import seedu.malitio.storage.Storage; +import seedu.malitio.storage.StorageManager; +import seedu.malitio.ui.Ui; +import seedu.malitio.ui.UiManager; import java.io.FileNotFoundException; import java.io.IOException; @@ -32,7 +32,7 @@ public class MainApp extends Application { private static final Logger logger = LogsCenter.getLogger(MainApp.class); - public static final Version VERSION = new Version(1, 0, 0, true); + public static final Version VERSION = new Version(0, 1, 0, true); protected Ui ui; protected Logic logic; @@ -45,11 +45,11 @@ public MainApp() {} @Override public void init() throws Exception { - logger.info("=============================[ Initializing AddressBook ]==========================="); + logger.info("=============================[ Initializing Malitio ]==========================="); super.init(); config = initConfig(getApplicationParameter("config")); - storage = new StorageManager(config.getAddressBookFilePath(), config.getUserPrefsFilePath()); + storage = new StorageManager(config.getMalitioFilePath(), config.getUserPrefsFilePath()); userPrefs = initPrefs(config); @@ -70,20 +70,20 @@ private String getApplicationParameter(String parameterName){ } private Model initModelManager(Storage storage, UserPrefs userPrefs) { - Optional addressBookOptional; - ReadOnlyAddressBook initialData; + Optional malitioOptional; + ReadOnlyMalitio initialData; try { - addressBookOptional = storage.readAddressBook(); - if(!addressBookOptional.isPresent()){ - logger.info("Data file not found. Will be starting with an empty AddressBook"); + malitioOptional = storage.readMalitio(); + if(!malitioOptional.isPresent()){ + logger.info("Data file not found. Will be starting with an empty Malitio"); } - initialData = addressBookOptional.orElse(new AddressBook()); + initialData = malitioOptional.orElse(new Malitio()); } catch (DataConversionException e) { - logger.warning("Data file not in the correct format. Will be starting with an empty AddressBook"); - initialData = new AddressBook(); + logger.warning("Data file not in the correct format. Will be starting with an empty Malitio"); + initialData = new Malitio(); } catch (IOException e) { - logger.warning("Problem while reading from the file. . Will be starting with an empty AddressBook"); - initialData = new AddressBook(); + logger.warning("Problem while reading from the file. . Will be starting with an empty Malitio"); + initialData = new Malitio(); } return new ModelManager(initialData, userPrefs); @@ -139,7 +139,7 @@ protected UserPrefs initPrefs(Config config) { "Using default user prefs"); initializedPrefs = new UserPrefs(); } catch (IOException e) { - logger.warning("Problem while reading from the file. . Will be starting with an empty AddressBook"); + logger.warning("Problem while reading from the file. . Will be starting with an empty Malitio"); initializedPrefs = new UserPrefs(); } @@ -159,13 +159,13 @@ private void initEventsCenter() { @Override public void start(Stage primaryStage) { - logger.info("Starting AddressBook " + MainApp.VERSION); + logger.info("Starting Malitio " + MainApp.VERSION); ui.start(primaryStage); } @Override public void stop() { - logger.info("============================ [ Stopping Address Book ] ============================="); + logger.info("============================ [ Stopping Malitio ] ============================="); ui.stop(); try { storage.saveUserPrefs(userPrefs); diff --git a/src/main/java/seedu/address/commons/core/ComponentManager.java b/src/main/java/seedu/malitio/commons/core/ComponentManager.java similarity index 87% rename from src/main/java/seedu/address/commons/core/ComponentManager.java rename to src/main/java/seedu/malitio/commons/core/ComponentManager.java index 4bc8564e5824..00b576e9a3c5 100644 --- a/src/main/java/seedu/address/commons/core/ComponentManager.java +++ b/src/main/java/seedu/malitio/commons/core/ComponentManager.java @@ -1,6 +1,6 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; -import seedu.address.commons.events.BaseEvent; +import seedu.malitio.commons.events.BaseEvent; /** * Base class for *Manager classes diff --git a/src/main/java/seedu/address/commons/core/Config.java b/src/main/java/seedu/malitio/commons/core/Config.java similarity index 66% rename from src/main/java/seedu/address/commons/core/Config.java rename to src/main/java/seedu/malitio/commons/core/Config.java index 6441c9ef20f4..5b0c0fc5d836 100644 --- a/src/main/java/seedu/address/commons/core/Config.java +++ b/src/main/java/seedu/malitio/commons/core/Config.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; import java.util.Objects; import java.util.logging.Level; @@ -9,13 +9,14 @@ public class Config { public static final String DEFAULT_CONFIG_FILE = "config.json"; + public static final String DEFAULT_FILE_PATH = "data/malitio.xml"; // Config values customizable through config file - private String appTitle = "Address App"; + private String appTitle = "Malitio"; private Level logLevel = Level.INFO; private String userPrefsFilePath = "preferences.json"; - private String addressBookFilePath = "data/addressbook.xml"; - private String addressBookName = "MyAddressBook"; + private String malitioFilePath = DEFAULT_FILE_PATH; + private String malitioName = "MyMalitio"; public Config() { @@ -45,20 +46,20 @@ public void setUserPrefsFilePath(String userPrefsFilePath) { this.userPrefsFilePath = userPrefsFilePath; } - public String getAddressBookFilePath() { - return addressBookFilePath; + public String getMalitioFilePath() { + return malitioFilePath; } - public void setAddressBookFilePath(String addressBookFilePath) { - this.addressBookFilePath = addressBookFilePath; + public void setMalitioFilePath(String malitioFilePath) { + this.malitioFilePath = malitioFilePath; } - public String getAddressBookName() { - return addressBookName; + public String getMalitioName() { + return malitioName; } - public void setAddressBookName(String addressBookName) { - this.addressBookName = addressBookName; + public void setMalitioName(String malitioName) { + this.malitioName = malitioName; } @@ -76,13 +77,13 @@ public boolean equals(Object other) { return Objects.equals(appTitle, o.appTitle) && Objects.equals(logLevel, o.logLevel) && Objects.equals(userPrefsFilePath, o.userPrefsFilePath) - && Objects.equals(addressBookFilePath, o.addressBookFilePath) - && Objects.equals(addressBookName, o.addressBookName); + && Objects.equals(malitioFilePath, o.malitioFilePath) + && Objects.equals(malitioName, o.malitioName); } @Override public int hashCode() { - return Objects.hash(appTitle, logLevel, userPrefsFilePath, addressBookFilePath, addressBookName); + return Objects.hash(appTitle, logLevel, userPrefsFilePath, malitioFilePath, malitioName); } @Override @@ -91,8 +92,8 @@ public String toString(){ sb.append("App title : " + appTitle); sb.append("\nCurrent log level : " + logLevel); sb.append("\nPreference file Location : " + userPrefsFilePath); - sb.append("\nLocal data file location : " + addressBookFilePath); - sb.append("\nAddressBook name : " + addressBookName); + sb.append("\nLocal data file location : " + malitioFilePath); + sb.append("\nMalitio name : " + malitioName); return sb.toString(); } diff --git a/src/main/java/seedu/address/commons/core/EventsCenter.java b/src/main/java/seedu/malitio/commons/core/EventsCenter.java similarity index 92% rename from src/main/java/seedu/address/commons/core/EventsCenter.java rename to src/main/java/seedu/malitio/commons/core/EventsCenter.java index 9652cd5c227b..b7ebc4409afa 100644 --- a/src/main/java/seedu/address/commons/core/EventsCenter.java +++ b/src/main/java/seedu/malitio/commons/core/EventsCenter.java @@ -1,7 +1,8 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; import com.google.common.eventbus.EventBus; -import seedu.address.commons.events.BaseEvent; + +import seedu.malitio.commons.events.BaseEvent; import java.util.logging.Logger; diff --git a/src/main/java/seedu/address/commons/core/GuiSettings.java b/src/main/java/seedu/malitio/commons/core/GuiSettings.java similarity index 98% rename from src/main/java/seedu/address/commons/core/GuiSettings.java rename to src/main/java/seedu/malitio/commons/core/GuiSettings.java index e157ac8b8679..75de09541106 100644 --- a/src/main/java/seedu/address/commons/core/GuiSettings.java +++ b/src/main/java/seedu/malitio/commons/core/GuiSettings.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; import java.awt.*; import java.io.Serializable; diff --git a/src/main/java/seedu/address/commons/core/LogsCenter.java b/src/main/java/seedu/malitio/commons/core/LogsCenter.java similarity index 96% rename from src/main/java/seedu/address/commons/core/LogsCenter.java rename to src/main/java/seedu/malitio/commons/core/LogsCenter.java index 17939bab4975..cfee487380f5 100644 --- a/src/main/java/seedu/address/commons/core/LogsCenter.java +++ b/src/main/java/seedu/malitio/commons/core/LogsCenter.java @@ -1,10 +1,10 @@ -package seedu.address.commons.core; - -import seedu.address.commons.events.BaseEvent; +package seedu.malitio.commons.core; import java.io.IOException; import java.util.logging.*; +import seedu.malitio.commons.events.BaseEvent; + /** * Configures and manages loggers and handlers, including their logging level * Named {@link Logger}s can be obtained from this class
@@ -15,7 +15,7 @@ public class LogsCenter { private static final int MAX_FILE_COUNT = 5; private static final int MAX_FILE_SIZE_IN_BYTES = (int) (Math.pow(2, 20) * 5); // 5MB - private static final String LOG_FILE = "addressbook.log"; + private static final String LOG_FILE = "malitio.log"; private static Level currentLogLevel = Level.INFO; private static final Logger logger = LogsCenter.getLogger(LogsCenter.class); private static FileHandler fileHandler; diff --git a/src/main/java/seedu/address/commons/core/Messages.java b/src/main/java/seedu/malitio/commons/core/Messages.java similarity index 51% rename from src/main/java/seedu/address/commons/core/Messages.java rename to src/main/java/seedu/malitio/commons/core/Messages.java index 1deb3a1e4695..71497aea1896 100644 --- a/src/main/java/seedu/address/commons/core/Messages.java +++ b/src/main/java/seedu/malitio/commons/core/Messages.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; /** * Container for user visible messages. @@ -7,7 +7,7 @@ public class Messages { public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command"; public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; - public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; - public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; + public static final String MESSAGE_INVALID_TASK_DISPLAYED_INDEX = "The task index provided is invalid"; + public static final String MESSAGE_TASKS_LISTED_OVERVIEW = "%1$d tasks found!"; } diff --git a/src/main/java/seedu/address/commons/core/UnmodifiableObservableList.java b/src/main/java/seedu/malitio/commons/core/UnmodifiableObservableList.java similarity index 99% rename from src/main/java/seedu/address/commons/core/UnmodifiableObservableList.java rename to src/main/java/seedu/malitio/commons/core/UnmodifiableObservableList.java index 5c25d8647a8d..31e6cafff35f 100644 --- a/src/main/java/seedu/address/commons/core/UnmodifiableObservableList.java +++ b/src/main/java/seedu/malitio/commons/core/UnmodifiableObservableList.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; import javafx.beans.InvalidationListener; import javafx.collections.ListChangeListener; diff --git a/src/main/java/seedu/address/commons/core/Version.java b/src/main/java/seedu/malitio/commons/core/Version.java similarity index 98% rename from src/main/java/seedu/address/commons/core/Version.java rename to src/main/java/seedu/malitio/commons/core/Version.java index 7ecb85b18f82..b59252850c41 100644 --- a/src/main/java/seedu/address/commons/core/Version.java +++ b/src/main/java/seedu/malitio/commons/core/Version.java @@ -1,4 +1,4 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/seedu/address/commons/events/BaseEvent.java b/src/main/java/seedu/malitio/commons/events/BaseEvent.java similarity index 90% rename from src/main/java/seedu/address/commons/events/BaseEvent.java rename to src/main/java/seedu/malitio/commons/events/BaseEvent.java index 723a9c69fbd5..a4e04154fd24 100644 --- a/src/main/java/seedu/address/commons/events/BaseEvent.java +++ b/src/main/java/seedu/malitio/commons/events/BaseEvent.java @@ -1,4 +1,4 @@ -package seedu.address.commons.events; +package seedu.malitio.commons.events; public abstract class BaseEvent { diff --git a/src/main/java/seedu/malitio/commons/events/model/MalitioChangedEvent.java b/src/main/java/seedu/malitio/commons/events/model/MalitioChangedEvent.java new file mode 100644 index 000000000000..c5ce31e58736 --- /dev/null +++ b/src/main/java/seedu/malitio/commons/events/model/MalitioChangedEvent.java @@ -0,0 +1,19 @@ +package seedu.malitio.commons.events.model; + +import seedu.malitio.commons.events.BaseEvent; +import seedu.malitio.model.ReadOnlyMalitio; + +/** Indicates the Malitio in the model has changed*/ +public class MalitioChangedEvent extends BaseEvent { + + public final ReadOnlyMalitio data; + + public MalitioChangedEvent(ReadOnlyMalitio data){ + this.data = data; + } + + @Override + public String toString() { + return "number of tasks " + data.getFloatingTaskList().size() + ", number of tags " + data.getTagList().size(); + } +} diff --git a/src/main/java/seedu/address/commons/events/storage/DataSavingExceptionEvent.java b/src/main/java/seedu/malitio/commons/events/storage/DataSavingExceptionEvent.java similarity index 78% rename from src/main/java/seedu/address/commons/events/storage/DataSavingExceptionEvent.java rename to src/main/java/seedu/malitio/commons/events/storage/DataSavingExceptionEvent.java index f0a0640ee523..83c2d7b67ed0 100644 --- a/src/main/java/seedu/address/commons/events/storage/DataSavingExceptionEvent.java +++ b/src/main/java/seedu/malitio/commons/events/storage/DataSavingExceptionEvent.java @@ -1,6 +1,6 @@ -package seedu.address.commons.events.storage; +package seedu.malitio.commons.events.storage; -import seedu.address.commons.events.BaseEvent; +import seedu.malitio.commons.events.BaseEvent; /** * Indicates an exception during a file saving diff --git a/src/main/java/seedu/address/commons/events/ui/ExitAppRequestEvent.java b/src/main/java/seedu/malitio/commons/events/ui/ExitAppRequestEvent.java similarity index 70% rename from src/main/java/seedu/address/commons/events/ui/ExitAppRequestEvent.java rename to src/main/java/seedu/malitio/commons/events/ui/ExitAppRequestEvent.java index 9af6194543a3..bc1e1adbf2d4 100644 --- a/src/main/java/seedu/address/commons/events/ui/ExitAppRequestEvent.java +++ b/src/main/java/seedu/malitio/commons/events/ui/ExitAppRequestEvent.java @@ -1,6 +1,6 @@ -package seedu.address.commons.events.ui; +package seedu.malitio.commons.events.ui; -import seedu.address.commons.events.BaseEvent; +import seedu.malitio.commons.events.BaseEvent; /** * Indicates a request for App termination diff --git a/src/main/java/seedu/address/commons/events/ui/IncorrectCommandAttemptedEvent.java b/src/main/java/seedu/malitio/commons/events/ui/IncorrectCommandAttemptedEvent.java similarity index 68% rename from src/main/java/seedu/address/commons/events/ui/IncorrectCommandAttemptedEvent.java rename to src/main/java/seedu/malitio/commons/events/ui/IncorrectCommandAttemptedEvent.java index 991f7ae9fa25..f4a3bc4869d1 100644 --- a/src/main/java/seedu/address/commons/events/ui/IncorrectCommandAttemptedEvent.java +++ b/src/main/java/seedu/malitio/commons/events/ui/IncorrectCommandAttemptedEvent.java @@ -1,7 +1,7 @@ -package seedu.address.commons.events.ui; +package seedu.malitio.commons.events.ui; -import seedu.address.commons.events.BaseEvent; -import seedu.address.logic.commands.Command; +import seedu.malitio.commons.events.BaseEvent; +import seedu.malitio.logic.commands.Command; /** * Indicates an attempt to execute an incorrect command diff --git a/src/main/java/seedu/address/commons/events/ui/JumpToListRequestEvent.java b/src/main/java/seedu/malitio/commons/events/ui/JumpToListRequestEvent.java similarity index 68% rename from src/main/java/seedu/address/commons/events/ui/JumpToListRequestEvent.java rename to src/main/java/seedu/malitio/commons/events/ui/JumpToListRequestEvent.java index 0580d27aecf5..47280b1d6a23 100644 --- a/src/main/java/seedu/address/commons/events/ui/JumpToListRequestEvent.java +++ b/src/main/java/seedu/malitio/commons/events/ui/JumpToListRequestEvent.java @@ -1,9 +1,9 @@ -package seedu.address.commons.events.ui; +package seedu.malitio.commons.events.ui; -import seedu.address.commons.events.BaseEvent; +import seedu.malitio.commons.events.BaseEvent; /** - * Indicates a request to jump to the list of persons + * Indicates a request to jump to the list of tasks */ public class JumpToListRequestEvent extends BaseEvent { diff --git a/src/main/java/seedu/address/commons/events/ui/ShowHelpRequestEvent.java b/src/main/java/seedu/malitio/commons/events/ui/ShowHelpRequestEvent.java similarity index 70% rename from src/main/java/seedu/address/commons/events/ui/ShowHelpRequestEvent.java rename to src/main/java/seedu/malitio/commons/events/ui/ShowHelpRequestEvent.java index a7e40940b2c7..52909c3d38e4 100644 --- a/src/main/java/seedu/address/commons/events/ui/ShowHelpRequestEvent.java +++ b/src/main/java/seedu/malitio/commons/events/ui/ShowHelpRequestEvent.java @@ -1,6 +1,6 @@ -package seedu.address.commons.events.ui; +package seedu.malitio.commons.events.ui; -import seedu.address.commons.events.BaseEvent; +import seedu.malitio.commons.events.BaseEvent; /** * An event requesting to view the help page. diff --git a/src/main/java/seedu/malitio/commons/events/ui/TaskPanelSelectionChangedEvent.java b/src/main/java/seedu/malitio/commons/events/ui/TaskPanelSelectionChangedEvent.java new file mode 100644 index 000000000000..d77ef9329978 --- /dev/null +++ b/src/main/java/seedu/malitio/commons/events/ui/TaskPanelSelectionChangedEvent.java @@ -0,0 +1,39 @@ +package seedu.malitio.commons.events.ui; + +import seedu.malitio.commons.events.BaseEvent; +import seedu.malitio.model.task.ReadOnlyDeadline; +import seedu.malitio.model.task.ReadOnlyEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; + +/** + * Represents a selection change in the Task List Panel + */ +public class TaskPanelSelectionChangedEvent extends BaseEvent { + + + private ReadOnlyFloatingTask newTaskSelection; + private ReadOnlyDeadline newDeadlineSelection; + private ReadOnlyEvent newEventSelection; + + public TaskPanelSelectionChangedEvent(ReadOnlyFloatingTask newSelection){ + this.newTaskSelection = newSelection; + } + + public TaskPanelSelectionChangedEvent(ReadOnlyDeadline newSelection){ + this.newDeadlineSelection = newSelection; + } + + public TaskPanelSelectionChangedEvent(ReadOnlyEvent newSelection){ + this.newEventSelection = newSelection; + } + + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } + + public ReadOnlyFloatingTask getNewSelection() { + return newTaskSelection; + } +} diff --git a/src/main/java/seedu/address/commons/exceptions/DataConversionException.java b/src/main/java/seedu/malitio/commons/exceptions/DataConversionException.java similarity index 84% rename from src/main/java/seedu/address/commons/exceptions/DataConversionException.java rename to src/main/java/seedu/malitio/commons/exceptions/DataConversionException.java index 1f689bd8e3f9..3980ce5c01da 100644 --- a/src/main/java/seedu/address/commons/exceptions/DataConversionException.java +++ b/src/main/java/seedu/malitio/commons/exceptions/DataConversionException.java @@ -1,4 +1,4 @@ -package seedu.address.commons.exceptions; +package seedu.malitio.commons.exceptions; /** * Represents an error during conversion of data from one format to another diff --git a/src/main/java/seedu/address/commons/exceptions/DuplicateDataException.java b/src/main/java/seedu/malitio/commons/exceptions/DuplicateDataException.java similarity index 85% rename from src/main/java/seedu/address/commons/exceptions/DuplicateDataException.java rename to src/main/java/seedu/malitio/commons/exceptions/DuplicateDataException.java index 17aa63d5020c..f3f3e82044cd 100644 --- a/src/main/java/seedu/address/commons/exceptions/DuplicateDataException.java +++ b/src/main/java/seedu/malitio/commons/exceptions/DuplicateDataException.java @@ -1,4 +1,4 @@ -package seedu.address.commons.exceptions; +package seedu.malitio.commons.exceptions; /** * Signals an error caused by duplicate data where there should be none. diff --git a/src/main/java/seedu/address/commons/exceptions/IllegalValueException.java b/src/main/java/seedu/malitio/commons/exceptions/IllegalValueException.java similarity index 88% rename from src/main/java/seedu/address/commons/exceptions/IllegalValueException.java rename to src/main/java/seedu/malitio/commons/exceptions/IllegalValueException.java index a473b43bd86f..0dd4fe34094d 100644 --- a/src/main/java/seedu/address/commons/exceptions/IllegalValueException.java +++ b/src/main/java/seedu/malitio/commons/exceptions/IllegalValueException.java @@ -1,4 +1,4 @@ -package seedu.address.commons.exceptions; +package seedu.malitio.commons.exceptions; /** * Signals that some given data does not fulfill some constraints. diff --git a/src/main/java/seedu/address/commons/util/AppUtil.java b/src/main/java/seedu/malitio/commons/util/AppUtil.java similarity index 81% rename from src/main/java/seedu/address/commons/util/AppUtil.java rename to src/main/java/seedu/malitio/commons/util/AppUtil.java index 649cc19aaeda..02136133424e 100644 --- a/src/main/java/seedu/address/commons/util/AppUtil.java +++ b/src/main/java/seedu/malitio/commons/util/AppUtil.java @@ -1,7 +1,7 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import javafx.scene.image.Image; -import seedu.address.MainApp; +import seedu.malitio.MainApp; /** * A container for App specific utility functions diff --git a/src/main/java/seedu/address/commons/util/CollectionUtil.java b/src/main/java/seedu/malitio/commons/util/CollectionUtil.java similarity index 96% rename from src/main/java/seedu/address/commons/util/CollectionUtil.java rename to src/main/java/seedu/malitio/commons/util/CollectionUtil.java index fde8394f31e5..06c4d1e08ebb 100644 --- a/src/main/java/seedu/address/commons/util/CollectionUtil.java +++ b/src/main/java/seedu/malitio/commons/util/CollectionUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import java.util.Collection; import java.util.HashSet; diff --git a/src/main/java/seedu/address/commons/util/ConfigUtil.java b/src/main/java/seedu/malitio/commons/util/ConfigUtil.java similarity index 91% rename from src/main/java/seedu/address/commons/util/ConfigUtil.java rename to src/main/java/seedu/malitio/commons/util/ConfigUtil.java index af42e03df06c..718faf4dabd0 100644 --- a/src/main/java/seedu/address/commons/util/ConfigUtil.java +++ b/src/main/java/seedu/malitio/commons/util/ConfigUtil.java @@ -1,8 +1,8 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; -import seedu.address.commons.core.Config; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.exceptions.DataConversionException; +import seedu.malitio.commons.core.Config; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.exceptions.DataConversionException; import java.io.File; import java.io.IOException; diff --git a/src/main/java/seedu/address/commons/util/FileUtil.java b/src/main/java/seedu/malitio/commons/util/FileUtil.java similarity index 98% rename from src/main/java/seedu/address/commons/util/FileUtil.java rename to src/main/java/seedu/malitio/commons/util/FileUtil.java index ca8221250de4..955b3cdf7b3d 100644 --- a/src/main/java/seedu/address/commons/util/FileUtil.java +++ b/src/main/java/seedu/malitio/commons/util/FileUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import java.io.File; import java.io.IOException; diff --git a/src/main/java/seedu/address/commons/util/FxViewUtil.java b/src/main/java/seedu/malitio/commons/util/FxViewUtil.java similarity index 92% rename from src/main/java/seedu/address/commons/util/FxViewUtil.java rename to src/main/java/seedu/malitio/commons/util/FxViewUtil.java index 900efa6bf5c3..e4c7a4950350 100644 --- a/src/main/java/seedu/address/commons/util/FxViewUtil.java +++ b/src/main/java/seedu/malitio/commons/util/FxViewUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import javafx.scene.Node; import javafx.scene.layout.AnchorPane; diff --git a/src/main/java/seedu/address/commons/util/JsonUtil.java b/src/main/java/seedu/malitio/commons/util/JsonUtil.java similarity index 98% rename from src/main/java/seedu/address/commons/util/JsonUtil.java rename to src/main/java/seedu/malitio/commons/util/JsonUtil.java index 80b67de5b7e8..47492725717e 100644 --- a/src/main/java/seedu/address/commons/util/JsonUtil.java +++ b/src/main/java/seedu/malitio/commons/util/JsonUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; diff --git a/src/main/java/seedu/address/commons/util/StringUtil.java b/src/main/java/seedu/malitio/commons/util/StringUtil.java similarity index 96% rename from src/main/java/seedu/address/commons/util/StringUtil.java rename to src/main/java/seedu/malitio/commons/util/StringUtil.java index 2e94740456a6..195cb52b9869 100644 --- a/src/main/java/seedu/address/commons/util/StringUtil.java +++ b/src/main/java/seedu/malitio/commons/util/StringUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/src/main/java/seedu/address/commons/util/UrlUtil.java b/src/main/java/seedu/malitio/commons/util/UrlUtil.java similarity index 94% rename from src/main/java/seedu/address/commons/util/UrlUtil.java rename to src/main/java/seedu/malitio/commons/util/UrlUtil.java index 6bbab52b9840..f7650cd5bf5e 100644 --- a/src/main/java/seedu/address/commons/util/UrlUtil.java +++ b/src/main/java/seedu/malitio/commons/util/UrlUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import java.net.URL; diff --git a/src/main/java/seedu/address/commons/util/XmlUtil.java b/src/main/java/seedu/malitio/commons/util/XmlUtil.java similarity index 98% rename from src/main/java/seedu/address/commons/util/XmlUtil.java rename to src/main/java/seedu/malitio/commons/util/XmlUtil.java index 2087e7628a1d..763ec2aee929 100644 --- a/src/main/java/seedu/address/commons/util/XmlUtil.java +++ b/src/main/java/seedu/malitio/commons/util/XmlUtil.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; diff --git a/src/main/java/seedu/malitio/logic/Logic.java b/src/main/java/seedu/malitio/logic/Logic.java new file mode 100644 index 000000000000..88c20067b4f8 --- /dev/null +++ b/src/main/java/seedu/malitio/logic/Logic.java @@ -0,0 +1,28 @@ +package seedu.malitio.logic; + +import javafx.collections.ObservableList; +import seedu.malitio.logic.commands.CommandResult; +import seedu.malitio.model.task.ReadOnlyDeadline; +import seedu.malitio.model.task.ReadOnlyEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; + +/** + * API of the Logic component + */ +public interface Logic { + /** + * Executes the command and returns the result. + * @param commandText The command as entered by the user. + * @return the result of the command execution. + */ + CommandResult execute(String commandText); + + /** Returns the filtered list of tasks */ + ObservableList getFilteredFloatingTaskList(); + + ObservableList getFilteredDeadlineList(); + + ObservableList getFilteredEventList(); + + +} diff --git a/src/main/java/seedu/malitio/logic/LogicManager.java b/src/main/java/seedu/malitio/logic/LogicManager.java new file mode 100644 index 000000000000..c96f7960d050 --- /dev/null +++ b/src/main/java/seedu/malitio/logic/LogicManager.java @@ -0,0 +1,53 @@ +package seedu.malitio.logic; + +import javafx.collections.ObservableList; +import seedu.malitio.commons.core.ComponentManager; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.logic.commands.Command; +import seedu.malitio.logic.commands.CommandResult; +import seedu.malitio.logic.parser.Parser; +import seedu.malitio.model.Model; +import seedu.malitio.model.task.ReadOnlyDeadline; +import seedu.malitio.model.task.ReadOnlyEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.storage.Storage; + +import java.util.logging.Logger; + +/** + * The main LogicManager of the app. + */ +public class LogicManager extends ComponentManager implements Logic { + private final Logger logger = LogsCenter.getLogger(LogicManager.class); + + private final Model model; + private final Parser parser; + + public LogicManager(Model model, Storage storage) { + this.model = model; + this.parser = new Parser(); + } + + @Override + public CommandResult execute(String commandText) { + logger.info("----------------[USER COMMAND][" + commandText + "]"); + Command command = parser.parseCommand(commandText); + command.setData(model); + return command.execute(); + } + + @Override + public ObservableList getFilteredFloatingTaskList() { + return model.getFilteredFloatingTaskList(); + } + + @Override + public ObservableList getFilteredDeadlineList() { + return model.getFilteredDeadlineList(); + } + + @Override + public ObservableList getFilteredEventList() { + return model.getFilteredEventList(); + } +} diff --git a/src/main/java/seedu/malitio/logic/commands/AddCommand.java b/src/main/java/seedu/malitio/logic/commands/AddCommand.java new file mode 100644 index 000000000000..290f78d98989 --- /dev/null +++ b/src/main/java/seedu/malitio/logic/commands/AddCommand.java @@ -0,0 +1,113 @@ +package seedu.malitio.logic.commands; + +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.*; + +import java.util.HashSet; +import java.util.Set; + +/** + * Adds a task to Malitio. + */ +public class AddCommand extends Command { + + public static final String COMMAND_WORD = "add"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a task to Malitio.\n" + + "Parameters: NAME [by DEADLINE] [start STARTTIME end ENDTIME] [t/TAG]...\n" + + "Example: " + COMMAND_WORD + + " Pay John $100 by 10112016 2359 t/oweMoney"; + + public static final String MESSAGE_SUCCESS = "New task added: %1$s"; + public static final String MESSAGE_DUPLICATE_TASK = "This floating task already exists in Malitio"; + public static final String MESSAGE_DUPLICATE_EVENT = "This event already exists in Malitio"; + private static final String MESSAGE_DUPLICATE_DEADLINE ="This deadline already exists in Malitio"; + private FloatingTask toAddFloatingTask; + private Deadline toAddDeadline; + private Event toAddEvent; + + /** + * Convenience constructor for floating tasks using raw values. + * + * @throws IllegalValueException if any of the raw values are invalid + */ + public AddCommand(String name, Set tags) + throws IllegalValueException { + final Set tagSet = new HashSet<>(); + for (String tagName : tags) { + tagSet.add(new Tag(tagName)); + } + this.toAddFloatingTask = new FloatingTask( + new Name(name), + new UniqueTagList(tagSet) + ); + } + + /** + * Convenience constructor for deadlines using raw values. + * + * @throws IllegalValueException if any of the raw values are invalid + */ + public AddCommand(String name, String date, Set tags) + throws IllegalValueException { + final Set tagSet = new HashSet<>(); + for (String tagName : tags) { + tagSet.add(new Tag(tagName)); + } + this.toAddDeadline = new Deadline( + new Name(name), + new DateTime(date), + new UniqueTagList(tagSet) + ); + } + + /** + * Convenience constructor for events using raw values. + * + * @throws IllegalValueException if any of the raw values are invalid + */ + public AddCommand(String name, String start, String end, Set tags) + throws IllegalValueException { + final Set tagSet = new HashSet<>(); + for (String tagName : tags) { + tagSet.add(new Tag(tagName)); + } + // check if start < end + this.toAddEvent = new Event( + new Name(name), + new DateTime(start), + new DateTime(end), + new UniqueTagList(tagSet) + ); + } + @Override + public CommandResult execute() { + assert model != null; + if (toAddFloatingTask!=null){ + try { + model.addFloatingTask(toAddFloatingTask); + return new CommandResult(String.format(MESSAGE_SUCCESS, toAddFloatingTask)); + } catch (UniqueFloatingTaskList.DuplicateFloatingTaskException e) { + return new CommandResult(MESSAGE_DUPLICATE_TASK); + } + } + else if (toAddDeadline != null){ + try { + model.addDeadline(toAddDeadline); + return new CommandResult(String.format(MESSAGE_SUCCESS, toAddDeadline)); + } catch (UniqueDeadlineList.DuplicateDeadlineException e) { + return new CommandResult(MESSAGE_DUPLICATE_DEADLINE); + } + } + else { + try { + model.addEvent(toAddEvent); + return new CommandResult(String.format(MESSAGE_SUCCESS, toAddEvent)); + } catch (UniqueEventList.DuplicateEventException e) { + return new CommandResult(MESSAGE_DUPLICATE_EVENT); + } + } + } +} diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/malitio/logic/commands/ClearCommand.java similarity index 53% rename from src/main/java/seedu/address/logic/commands/ClearCommand.java rename to src/main/java/seedu/malitio/logic/commands/ClearCommand.java index 522d57189f51..293c9ce5fc47 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/malitio/logic/commands/ClearCommand.java @@ -1,14 +1,14 @@ -package seedu.address.logic.commands; +package seedu.malitio.logic.commands; -import seedu.address.model.AddressBook; +import seedu.malitio.model.Malitio; /** - * Clears the address book. + * Clears the malitio. */ public class ClearCommand extends Command { public static final String COMMAND_WORD = "clear"; - public static final String MESSAGE_SUCCESS = "Address book has been cleared!"; + public static final String MESSAGE_SUCCESS = "Malitio has been cleared!"; public ClearCommand() {} @@ -16,7 +16,7 @@ public ClearCommand() {} @Override public CommandResult execute() { assert model != null; - model.resetData(AddressBook.getEmptyAddressBook()); + model.resetData(Malitio.getEmptymalitio()); return new CommandResult(MESSAGE_SUCCESS); } } diff --git a/src/main/java/seedu/address/logic/commands/Command.java b/src/main/java/seedu/malitio/logic/commands/Command.java similarity index 67% rename from src/main/java/seedu/address/logic/commands/Command.java rename to src/main/java/seedu/malitio/logic/commands/Command.java index 7c0ba2fd0161..5ab54a5ef83d 100644 --- a/src/main/java/seedu/address/logic/commands/Command.java +++ b/src/main/java/seedu/malitio/logic/commands/Command.java @@ -1,9 +1,9 @@ -package seedu.address.logic.commands; +package seedu.malitio.logic.commands; -import seedu.address.commons.core.EventsCenter; -import seedu.address.commons.core.Messages; -import seedu.address.commons.events.ui.IncorrectCommandAttemptedEvent; -import seedu.address.model.Model; +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.commons.core.Messages; +import seedu.malitio.commons.events.ui.IncorrectCommandAttemptedEvent; +import seedu.malitio.model.Model; /** * Represents a command with hidden internal logic and the ability to be executed. @@ -12,13 +12,13 @@ public abstract class Command { protected Model model; /** - * Constructs a feedback message to summarise an operation that displayed a listing of persons. + * Constructs a feedback message to summarise an operation that displayed a listing of tasks. * * @param displaySize used to generate summary - * @return summary message for persons displayed + * @return summary message for tasks displayed */ - public static String getMessageForPersonListShownSummary(int displaySize) { - return String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, displaySize); + public static String getMessageForTaskListShownSummary(int displaySize) { + return String.format(Messages.MESSAGE_TASKS_LISTED_OVERVIEW, displaySize); } /** diff --git a/src/main/java/seedu/address/logic/commands/CommandResult.java b/src/main/java/seedu/malitio/logic/commands/CommandResult.java similarity index 87% rename from src/main/java/seedu/address/logic/commands/CommandResult.java rename to src/main/java/seedu/malitio/logic/commands/CommandResult.java index f46f2f31353e..2a7b1cd0b271 100644 --- a/src/main/java/seedu/address/logic/commands/CommandResult.java +++ b/src/main/java/seedu/malitio/logic/commands/CommandResult.java @@ -1,4 +1,4 @@ -package seedu.address.logic.commands; +package seedu.malitio.logic.commands; /** * Represents the result of a command execution. diff --git a/src/main/java/seedu/malitio/logic/commands/DeleteCommand.java b/src/main/java/seedu/malitio/logic/commands/DeleteCommand.java new file mode 100644 index 000000000000..5597c17e59f3 --- /dev/null +++ b/src/main/java/seedu/malitio/logic/commands/DeleteCommand.java @@ -0,0 +1,50 @@ +package seedu.malitio.logic.commands; + +import seedu.malitio.commons.core.Messages; +import seedu.malitio.commons.core.UnmodifiableObservableList; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.model.task.UniqueFloatingTaskList.FloatingTaskNotFoundException; + +/** + * Deletes a task identified using it's last displayed index from Malitio. + */ +public class DeleteCommand extends Command { + + public static final String COMMAND_WORD = "delete"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Deletes the task identified by the index number used in the last task listing.\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + COMMAND_WORD + " 1"; + + public static final String MESSAGE_DELETE_TASK_SUCCESS = "Deleted Task: %1$s"; + + public final int targetIndex; + + public DeleteCommand(int targetIndex) { + this.targetIndex = targetIndex; + } + + + @Override + public CommandResult execute() { + + UnmodifiableObservableList lastShownList = model.getFilteredFloatingTaskList(); + + if (lastShownList.size() < targetIndex) { + indicateAttemptToExecuteIncorrectCommand(); + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + + ReadOnlyFloatingTask taskToDelete = lastShownList.get(targetIndex - 1); + + try { + model.deleteTask(taskToDelete); + } catch (FloatingTaskNotFoundException pnfe) { + assert false : "The target task cannot be missing"; + } + + return new CommandResult(String.format(MESSAGE_DELETE_TASK_SUCCESS, taskToDelete)); + } + +} diff --git a/src/main/java/seedu/malitio/logic/commands/EditCommand.java b/src/main/java/seedu/malitio/logic/commands/EditCommand.java new file mode 100644 index 000000000000..c18e1617fcd5 --- /dev/null +++ b/src/main/java/seedu/malitio/logic/commands/EditCommand.java @@ -0,0 +1,144 @@ +package seedu.malitio.logic.commands; + +import java.util.HashSet; +import java.util.Set; + +import seedu.malitio.commons.core.Messages; +import seedu.malitio.commons.core.UnmodifiableObservableList; +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.FloatingTask; +import seedu.malitio.model.task.Name; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.model.task.UniqueFloatingTaskList; +import seedu.malitio.model.task.UniqueFloatingTaskList.FloatingTaskNotFoundException; + +/** + * Edits a task identified using it's last displayed index from Malitio. + * Only the attribute(s) that require changes is(are) entered. + * @author Bel + * + */ +public class EditCommand extends Command{ + + public static final String COMMAND_WORD = "edit"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ":Edits the name of the task task identified by the index number used in the last task listing.\n" + + "Parameters: INDEX (must be a positive integer) NAME\n" + + "Example: " + COMMAND_WORD + " 1 New Name"; + + public static final String MESSAGE_DUPLICATE_TASK = "The intended edit correspond to a pre-existing task in Malitio"; + + private final int targetIndex; + + private final FloatingTask editedTask; + + public static final String MESSAGE_EDIT_TASK_SUCCESS = "Successfully edited task.\nOld: %1$s\nNew: %2$s"; + +/* private String newName; + + private Start start; + + private End end; + + private By by; + + private Set tagSet; + + private boolean isNameChanged = false; + + private boolean isStartChanged = false; + + private boolean isEndChanged = false; + + private boolean isByChanged = false; + + private boolean isTagsChanged = false; + +*/ + public EditCommand(int targetIndex, String name, Set newTags) + throws IllegalValueException { + this.targetIndex = targetIndex; + final Set tagSet = new HashSet<>(); + for (String tagName : newTags) { + tagSet.add(new Tag(tagName)); + } + this.editedTask = new FloatingTask( + new Name(name), + new UniqueTagList(tagSet) + ); + } + +/* + public EditCommand(int targetIndex, String name, Start start, End end, By by, Set newTags) { + checkIsNameModified(name); + checkIsStartModified(start); + checkIsEndModified(end); + checkIsByModified(by); + checkIsTagsModified(newTags); + + } + + private void checkIsTagsModified(Set newTags) throws IllegalValueException { + if (newTags != null) { + isTagsChanged = true; + this.tagSet = new HashSet<>(); + for (String tagName : tags) { + tagSet.add(new Tag(tagName)); + } + } + } + + private void checkIsByModified(By by) { + if (by!=null) { + this.by = by; + isByChanged = true; + } + } + + private void checkIsEndModified(End end) { + if (end!=null) { + this.end = end; + isEndChanged = true; + } + } + + private void checkIsStartModified(Start start) { + if (start!=null) { + this.start = start; + isStartChanged = true; + } + } + + private void checkIsNameModified(String name) { + if (name!=null) { + isNameChanged = true; + this.newName = name; + } + } + */ + @Override + public CommandResult execute() { + UnmodifiableObservableList lastShownList = model.getFilteredFloatingTaskList(); + if (lastShownList.size() < targetIndex) { + indicateAttemptToExecuteIncorrectCommand(); + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + + ReadOnlyFloatingTask taskToEdit = lastShownList.get(targetIndex - 1); + + try { + assert model != null; + model.addFloatingTask(editedTask); + model.deleteTask(taskToEdit); + } catch (FloatingTaskNotFoundException pnfe) { + assert false : "The target task cannot be missing"; + } catch (UniqueFloatingTaskList.DuplicateFloatingTaskException e) { + return new CommandResult(MESSAGE_DUPLICATE_TASK); + } + return new CommandResult(String.format(MESSAGE_EDIT_TASK_SUCCESS, taskToEdit, editedTask)); + } + +} diff --git a/src/main/java/seedu/address/logic/commands/ExitCommand.java b/src/main/java/seedu/malitio/logic/commands/ExitCommand.java similarity index 69% rename from src/main/java/seedu/address/logic/commands/ExitCommand.java rename to src/main/java/seedu/malitio/logic/commands/ExitCommand.java index d98233ce2a0b..a7066c3c4f5a 100644 --- a/src/main/java/seedu/address/logic/commands/ExitCommand.java +++ b/src/main/java/seedu/malitio/logic/commands/ExitCommand.java @@ -1,7 +1,7 @@ -package seedu.address.logic.commands; +package seedu.malitio.logic.commands; -import seedu.address.commons.core.EventsCenter; -import seedu.address.commons.events.ui.ExitAppRequestEvent; +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.commons.events.ui.ExitAppRequestEvent; /** * Terminates the program. @@ -10,7 +10,7 @@ public class ExitCommand extends Command { public static final String COMMAND_WORD = "exit"; - public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting Address Book as requested ..."; + public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting Malitio as requested ..."; public ExitCommand() {} diff --git a/src/main/java/seedu/malitio/logic/commands/FindCommand.java b/src/main/java/seedu/malitio/logic/commands/FindCommand.java new file mode 100644 index 000000000000..9c3ed0078c19 --- /dev/null +++ b/src/main/java/seedu/malitio/logic/commands/FindCommand.java @@ -0,0 +1,50 @@ +package seedu.malitio.logic.commands; + +import java.util.Set; + +/** + * Finds and lists all tasks in Malitio whose name contains any of the argument keywords. + * Keyword matching is case sensitive. + */ +public class FindCommand extends Command { + + public static final String COMMAND_WORD = "find"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all tasks whose names contain any of " + + "the specified keywords (case-sensitive) and displays them as a list with index numbers.\n" + + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" + + "Example: " + COMMAND_WORD + " alice bob charlie"; + + private final Set keywords; + private final String type; + + public FindCommand(String type, Set keywords) { + this.keywords = keywords; + this.type = type; + } + + @Override + public CommandResult execute() { + + switch (type) { + case "f": + model.updateFilteredTaskList(keywords); + return new CommandResult(getMessageForTaskListShownSummary(model.getFilteredFloatingTaskList().size())); + case "d": + model.updateFilteredDeadlineList(keywords); + return new CommandResult(getMessageForTaskListShownSummary(model.getFilteredDeadlineList().size())); + case "e": + model.updateFilteredEventList(keywords); + return new CommandResult(getMessageForTaskListShownSummary(model.getFilteredEventList().size())); + default: + model.updateFilteredTaskList(keywords); + model.updateFilteredDeadlineList(keywords); + model.updateFilteredEventList(keywords); + return new CommandResult(getMessageForTaskListShownSummary( + model.getFilteredFloatingTaskList().size() + + model.getFilteredDeadlineList().size() + + model.getFilteredEventList().size())); + } + } + +} diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/malitio/logic/commands/HelpCommand.java similarity index 80% rename from src/main/java/seedu/address/logic/commands/HelpCommand.java rename to src/main/java/seedu/malitio/logic/commands/HelpCommand.java index 65af96940242..d22153c4f640 100644 --- a/src/main/java/seedu/address/logic/commands/HelpCommand.java +++ b/src/main/java/seedu/malitio/logic/commands/HelpCommand.java @@ -1,8 +1,8 @@ -package seedu.address.logic.commands; +package seedu.malitio.logic.commands; -import seedu.address.commons.core.EventsCenter; -import seedu.address.commons.events.ui.ShowHelpRequestEvent; +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.commons.events.ui.ShowHelpRequestEvent; /** * Format full help instructions for every command for display. diff --git a/src/main/java/seedu/address/logic/commands/IncorrectCommand.java b/src/main/java/seedu/malitio/logic/commands/IncorrectCommand.java similarity index 92% rename from src/main/java/seedu/address/logic/commands/IncorrectCommand.java rename to src/main/java/seedu/malitio/logic/commands/IncorrectCommand.java index 491d9cb9da35..0604608bb8ac 100644 --- a/src/main/java/seedu/address/logic/commands/IncorrectCommand.java +++ b/src/main/java/seedu/malitio/logic/commands/IncorrectCommand.java @@ -1,4 +1,4 @@ -package seedu.address.logic.commands; +package seedu.malitio.logic.commands; /** diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/malitio/logic/commands/ListCommand.java similarity index 54% rename from src/main/java/seedu/address/logic/commands/ListCommand.java rename to src/main/java/seedu/malitio/logic/commands/ListCommand.java index 9bdd457a1b01..369be9ea31e5 100644 --- a/src/main/java/seedu/address/logic/commands/ListCommand.java +++ b/src/main/java/seedu/malitio/logic/commands/ListCommand.java @@ -1,20 +1,20 @@ -package seedu.address.logic.commands; +package seedu.malitio.logic.commands; /** - * Lists all persons in the address book to the user. + * Lists all tasks in Malitio to the user. */ public class ListCommand extends Command { public static final String COMMAND_WORD = "list"; - public static final String MESSAGE_SUCCESS = "Listed all persons"; + public static final String MESSAGE_SUCCESS = "Listed all tasks"; public ListCommand() {} @Override public CommandResult execute() { - model.updateFilteredListToShowAll(); + model.updateFilteredTaskListToShowAll(); return new CommandResult(MESSAGE_SUCCESS); } } diff --git a/src/main/java/seedu/malitio/logic/commands/SelectCommand.java b/src/main/java/seedu/malitio/logic/commands/SelectCommand.java new file mode 100644 index 000000000000..12967b39f90d --- /dev/null +++ b/src/main/java/seedu/malitio/logic/commands/SelectCommand.java @@ -0,0 +1,44 @@ +package seedu.malitio.logic.commands; + +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.commons.core.Messages; +import seedu.malitio.commons.core.UnmodifiableObservableList; +import seedu.malitio.commons.events.ui.JumpToListRequestEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; + +/** + * Selects a task identified using it's last displayed index from the malitio. + */ +public class SelectCommand extends Command { + + public final int targetIndex; + + public static final String COMMAND_WORD = "select"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Selects the task identified by the index number used in the last task listing.\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + COMMAND_WORD + " 1"; + + public static final String MESSAGE_SELECT_TASK_SUCCESS = "Selected Task: %1$s"; + + public SelectCommand(int targetIndex) { + this.targetIndex = targetIndex; + } + + @Override + public CommandResult execute() { + + UnmodifiableObservableList lastShownList = model.getFilteredFloatingTaskList(); + + if (lastShownList.size() < targetIndex) { + indicateAttemptToExecuteIncorrectCommand(); + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + + EventsCenter.getInstance().post(new JumpToListRequestEvent(targetIndex - 1)); + return new CommandResult(String.format(MESSAGE_SELECT_TASK_SUCCESS, targetIndex)); + + } + +} diff --git a/src/main/java/seedu/malitio/logic/parser/Parser.java b/src/main/java/seedu/malitio/logic/parser/Parser.java new file mode 100644 index 000000000000..07e5911d25ec --- /dev/null +++ b/src/main/java/seedu/malitio/logic/parser/Parser.java @@ -0,0 +1,319 @@ +package seedu.malitio.logic.parser; + +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.commons.util.StringUtil; +import seedu.malitio.logic.commands.*; +import seedu.malitio.model.task.Name; + +import static seedu.malitio.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.malitio.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Parses user input. + */ +public class Parser { + + /** + * Used for initial separation of command word and args. + */ + private static final Pattern BASIC_COMMAND_FORMAT = Pattern.compile("(?\\S+)(?.*)"); + + private static final Pattern TASK_INDEX_ARGS_FORMAT = Pattern.compile("(?.+)"); + + private static final Pattern KEYWORDS_ARGS_FORMAT = + Pattern.compile("(?\\S+(?:\\s+\\S+)*)"); // one or more keywords separated by whitespace + + private static final Pattern TASK_DATA_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes + Pattern.compile("(?[^/]+)" + + "(?(?: t/[^/]+)*)"); // variable number of tags + + private static final Pattern EDIT_DATA_ARGS_FORMAT = + Pattern.compile("(?[0-9]+)" + + "(?[^/]+)" + + "(?(?: t/[^/]+)*)"); + + private static final Set TYPES_OF_TASKS = new HashSet(Arrays.asList("f", "d", "e" )); + + public Parser() {} + + /** + * Parses user input into command for execution. + * + * @param userInput full user input string + * @return the command based on the user input + */ + public Command parseCommand(String userInput) { + final Matcher matcher = BASIC_COMMAND_FORMAT.matcher(userInput.trim()); + if (!matcher.matches()) { + return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE)); + } + + final String commandWord = matcher.group("commandWord"); + final String arguments = matcher.group("arguments"); + switch (commandWord) { + + case AddCommand.COMMAND_WORD: + return prepareAdd(arguments); + + case EditCommand.COMMAND_WORD: + return prepareEdit(arguments); + + case SelectCommand.COMMAND_WORD: + return prepareSelect(arguments); + + case DeleteCommand.COMMAND_WORD: + return prepareDelete(arguments); + + case ClearCommand.COMMAND_WORD: + return new ClearCommand(); + + case FindCommand.COMMAND_WORD: + return prepareFind(arguments); + + case ListCommand.COMMAND_WORD: + return new ListCommand(); + + case ExitCommand.COMMAND_WORD: + return new ExitCommand(); + + case HelpCommand.COMMAND_WORD: + return new HelpCommand(); + + default: + return new IncorrectCommand(MESSAGE_UNKNOWN_COMMAND); + } + } + + /** + * Parses arguments in the context of the add task command. + * + * @param args full command args string + * @return the prepared command + */ + private Command prepareAdd(String args){ + final Matcher matcher = TASK_DATA_ARGS_FORMAT.matcher(args.trim()); + boolean hasStart = false; + boolean hasEnd = false; + // Validate arg string format + if (!matcher.matches()) { + return new IncorrectCommand(String.format(Name.MESSAGE_NAME_CONSTRAINTS, AddCommand.MESSAGE_USAGE)); + + } + try { + String name = matcher.group("name"); + String deadline = getDeadlineFromArgs(name); + if (!deadline.isEmpty()) { + name = name.replaceAll("by " + deadline, ""); + } + String start = getStartFromArgs(name); + if (!start.isEmpty()) { + name = name.replaceAll("start " + start, ""); + hasStart = true; + } + String end = getEndFromArgs(name); + if (!end.isEmpty()) { + name = name.replaceAll("end " + end, ""); + hasEnd = true; + } + if (!deadline.isEmpty()) { + return new AddCommand( + name, + deadline, + getTagsFromArgs(matcher.group("tagArguments")) + ); + } else if (hasStart && hasEnd) { + return new AddCommand( + name, + start, + end, + getTagsFromArgs(matcher.group("tagArguments")) + ); + } else if (hasStart ^ hasEnd) { + return new IncorrectCommand("Expecting start and end times\nExample: start 10032016 1200 end 10032016 1300"); + } + return new AddCommand( + name, + getTagsFromArgs(matcher.group("tagArguments")) + ); + } catch (IllegalValueException ive) { + return new IncorrectCommand(ive.getMessage()); + } + } + + private static String getDeadlineFromArgs(String args) throws IllegalValueException { + int byIndex = args.lastIndexOf("by"); + String deadline = ""; + if(byIndex > 0 && byIndex < args.length() - 2) { + try { + deadline = args.substring(byIndex + 3); + if (deadline.matches("[^\\d]+")) { + return ""; + } else if (!deadline.matches("\\d{8} \\d{4}")) { + throw new IllegalValueException("Expecting 8 numbers followed by 4 numbers\nExample: by 03122016 1320"); + } + } catch (IndexOutOfBoundsException iob){ + throw new IllegalValueException("Expecting 8 numbers followed by 4 numbers\nExample: by 03122016 1320"); + } + } + return deadline; + } + + private static String getStartFromArgs(String args) throws IllegalValueException { + int startIndex = args.lastIndexOf("start"); + String start = ""; + if(startIndex > 0 && startIndex < args.length() - 2) { + try { + start = args.substring(startIndex + 6, startIndex + 19); + if (start.matches("[^\\d]+")) { + return ""; + } + else if (!start.matches("\\d{8} \\d{4}")) { + throw new IllegalValueException("Expecting 8 numbers followed by 4 numbers"); + } + } catch (IndexOutOfBoundsException iob){ + throw new IllegalValueException("Expecting 8 numbers followed by 4 numbers"); + } + } + return start; + } + + private static String getEndFromArgs(String args) throws IllegalValueException { + int endIndex = args.lastIndexOf("end"); + String end = ""; + if(endIndex > 0 && endIndex < args.length() - 2) { + try { + end = args.substring(endIndex + 4, endIndex + 17); + if (end.matches("[^\\d]+")) { + return ""; + } else if (!end.matches("\\d{8} \\d{4}")) { + throw new IllegalValueException("Expecting 8 numbers followed by 4 numbers"); + } + } catch (IndexOutOfBoundsException iob){ + throw new IllegalValueException("Expecting 8 numbers followed by 4 numbers"); + } + } + return end; + } + + /** + * Extracts the new task's tags from the add command's tag arguments string. + * Merges duplicate tag strings. + */ + private static Set getTagsFromArgs(String tagArguments) throws IllegalValueException { + // no tags + if (tagArguments.isEmpty()) { + return Collections.emptySet(); + } + // replace first delimiter prefix, then split + final Collection tagStrings = Arrays.asList(tagArguments.replaceFirst(" t/", "").split(" t/")); + return new HashSet<>(tagStrings); + } + + + /** + * + * @param arguments + * @return the prepared command + * @author Bel + */ + private Command prepareEdit(String args) { + final Matcher matcher = EDIT_DATA_ARGS_FORMAT.matcher(args.trim()); + // Validate arg string format + if (!matcher.matches()) { + return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE)); + } + try { + Optional index = parseIndex(matcher.group("targetIndex")); + return new EditCommand( + index.get(), + matcher.group("name"), + getTagsFromArgs(matcher.group("tagArguments")) + ); + } catch (IllegalValueException ive) { + return new IncorrectCommand(ive.getMessage()); + } + } + + /** + * Parses arguments in the context of the delete task command. + * + * @param args full command args string + * @return the prepared command + */ + private Command prepareDelete(String args) { + + Optional index = parseIndex(args); + if(!index.isPresent()){ + return new IncorrectCommand( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); + } + + return new DeleteCommand(index.get()); + } + + /** + * Parses arguments in the context of the select task command. + * + * @param args full command args string + * @return the prepared command + */ + private Command prepareSelect(String args) { + Optional index = parseIndex(args); + if(!index.isPresent()){ + return new IncorrectCommand( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, SelectCommand.MESSAGE_USAGE)); + } + + return new SelectCommand(index.get()); + } + + /** + * Returns the specified index in the {@code command} IF a positive unsigned integer is given as the index. + * Returns an {@code Optional.empty()} otherwise. + */ + private Optional parseIndex(String command) { + final Matcher matcher = TASK_INDEX_ARGS_FORMAT.matcher(command.trim()); + if (!matcher.matches()) { + return Optional.empty(); + } + + String index = matcher.group("targetIndex"); + if(!StringUtil.isUnsignedInteger(index)){ + return Optional.empty(); + } + return Optional.of(Integer.parseInt(index)); + + } + + /** + * Parses arguments in the context of the find task command. + * + * @param args full command args string + * @return the prepared command + */ + private Command prepareFind(String args) { + final Matcher matcher = KEYWORDS_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + FindCommand.MESSAGE_USAGE)); + } + + // keywords delimited by whitespace + String[] keywords = matcher.group("keywords").split("\\s+"); + String typeOfTask = ""; + + if(TYPES_OF_TASKS.contains(keywords[0])) { + typeOfTask = keywords[0]; + } + final Set keywordSet = new HashSet<>(Arrays.asList(keywords)); + return new FindCommand(typeOfTask, keywordSet); + } + +} \ No newline at end of file diff --git a/src/main/java/seedu/malitio/logic/parser/Parser.java.rej b/src/main/java/seedu/malitio/logic/parser/Parser.java.rej new file mode 100644 index 000000000000..a99c9dfddfb3 --- /dev/null +++ b/src/main/java/seedu/malitio/logic/parser/Parser.java.rej @@ -0,0 +1,11 @@ +diff a/src/main/java/seedu/malitio/logic/parser/Parser.java b/src/main/java/seedu/malitio/logic/parser/Parser.java (rejected hunks) +@@ -51,9 +51,6 @@ + + case AddCommand.COMMAND_WORD: + return prepareAdd(arguments); +- +- case EditCommand.COMMAND_WORD: +- return prepareEdit(arguments); + + case SelectCommand.COMMAND_WORD: + return prepareSelect(arguments); diff --git a/src/main/java/seedu/malitio/model/Malitio.java b/src/main/java/seedu/malitio/model/Malitio.java new file mode 100644 index 000000000000..ba4a4e2bf1ba --- /dev/null +++ b/src/main/java/seedu/malitio/model/Malitio.java @@ -0,0 +1,282 @@ +package seedu.malitio.model; + +import javafx.collections.ObservableList; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.Deadline; +import seedu.malitio.model.task.Event; +import seedu.malitio.model.task.FloatingTask; +import seedu.malitio.model.task.ReadOnlyDeadline; +import seedu.malitio.model.task.ReadOnlyEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.model.task.UniqueDeadlineList; +import seedu.malitio.model.task.UniqueEventList; +import seedu.malitio.model.task.UniqueFloatingTaskList; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Wraps all data at the application level + * Duplicates are not allowed (by .equals comparison) + */ +public class Malitio implements ReadOnlyMalitio { + + private final UniqueFloatingTaskList tasks; + private final UniqueDeadlineList deadlines; + private final UniqueEventList events; + private final UniqueTagList tags; + + { + tasks = new UniqueFloatingTaskList(); + deadlines = new UniqueDeadlineList(); + events = new UniqueEventList(); + tags = new UniqueTagList(); + } + + public Malitio() {} + + /** + * Tasks, Schedules and Tags are copied into this Malitio + */ + public Malitio(ReadOnlyMalitio toBeCopied) { + this(toBeCopied.getUniqueFloatingTaskList(), toBeCopied.getUniqueDeadlineList(), toBeCopied.getUniqueEventList(), toBeCopied.getUniqueTagList()); + } + + /** + * Tasks and Tags are copied into this Malitio + */ + public Malitio(UniqueFloatingTaskList tasks, UniqueDeadlineList deadlines, UniqueEventList event, UniqueTagList tags) { + resetData(tasks.getInternalList(), deadlines.getInternalList(), event.getInternalList(), tags.getInternalList()); + } + + public static ReadOnlyMalitio getEmptymalitio() { + return new Malitio(); + } + +//// list overwrite operations + + public ObservableList getFloatingTasks() { + return tasks.getInternalList(); + } + + public ObservableList getDeadlines() { + return deadlines.getInternalList(); + } + + public ObservableList getEvents() { + return events.getInternalList(); + } + + public void setTasks(List floatingTask) { + this.tasks.getInternalList().setAll(floatingTask); + } + + public void setDeadlines(List deadlines) { + this.deadlines.getInternalList().setAll(deadlines); + } + + public void setEvents(List events) { + this.events.getInternalList().setAll(events); + } + + public void setTags(Collection tags) { + this.tags.getInternalList().setAll(tags); + } + + public void resetData(Collection newTasks, Collection newDeadlines,Collection newEvents, Collection newTags) { + setTasks(newTasks.stream().map(FloatingTask::new).collect(Collectors.toList())); + setDeadlines(newDeadlines.stream().map(Deadline::new).collect(Collectors.toList())); + setEvents(newEvents.stream().map(Event::new).collect(Collectors.toList())); + setTags(newTags); + } + + public void resetData(ReadOnlyMalitio newData) { + resetData(newData.getFloatingTaskList(), newData.getDeadlineList(), newData.getEventList(), newData.getTagList()); + } + +//// task-level operations + + /** + * Adds a task to Malitio. + * Also checks the new task's tags and updates {@link #tags} with any new tags found, + * and updates the Tag objects in the task to point to those in {@link #tags}. + * + * @throws UniqueFloatingTaskList.DuplicateFloatingTaskException if an equivalent task already exists. + */ + public void addFloatingTask(FloatingTask p) throws UniqueFloatingTaskList.DuplicateFloatingTaskException { + syncTagsWithMasterList(p); + tasks.add(p); + } + + /** + * Adds a deadline to Malitio. + * Also checks the new Deadline's tags and updates {@link #tags} with any new tags found, + * and updates the Tag objects in the deadline to point to those in {@link #tags}. + * + * @throws UniqueDeadlineList.DuplicateDeadlineException if an equivalent deadline already exists. + */ + public void addDeadline(Deadline p) throws UniqueDeadlineList.DuplicateDeadlineException { + syncTagsWithMasterList(p); + deadlines.add(p); + } + + /** + * Adds a event to Malitio. + * Also checks the new Event's tags and updates {@link #tags} with any new tags found, + * and updates the Tag objects in the event to point to those in {@link #tags}. + * + * @throws UniqueEventList.DuplicateEventException if an equivalent event already exists. + */ + public void addEvent(Event p) throws UniqueEventList.DuplicateEventException { + syncTagsWithMasterList(p); + events.add(p); + } + + /** + * Ensures that every tag in this task: + * - exists in the master list {@link #tags} + * - points to a Tag object in the master list + */ + private void syncTagsWithMasterList(FloatingTask task) { + final UniqueTagList taskTags = task.getTags(); + tags.mergeFrom(taskTags); + + // Create map with values = tag object references in the master list + final Map masterTagObjects = new HashMap<>(); + for (Tag tag : tags) { + masterTagObjects.put(tag, tag); + } + + // Rebuild the list of task tags using references from the master list + final Set commonTagReferences = new HashSet<>(); + for (Tag tag : taskTags) { + commonTagReferences.add(masterTagObjects.get(tag)); + } + task.setTags(new UniqueTagList(commonTagReferences)); + } + + private void syncTagsWithMasterList(Deadline deadline) { + final UniqueTagList taskTags = deadline.getTags(); + tags.mergeFrom(taskTags); + + // Create map with values = tag object references in the master list + final Map masterTagObjects = new HashMap<>(); + for (Tag tag : tags) { + masterTagObjects.put(tag, tag); + } + + // Rebuild the list of task tags using references from the master list + final Set commonTagReferences = new HashSet<>(); + for (Tag tag : taskTags) { + commonTagReferences.add(masterTagObjects.get(tag)); + } + deadline.setTags(new UniqueTagList(commonTagReferences)); + } + + private void syncTagsWithMasterList(Event event) { + final UniqueTagList taskTags = event.getTags(); + tags.mergeFrom(taskTags); + + // Create map with values = tag object references in the master list + final Map masterTagObjects = new HashMap<>(); + for (Tag tag : tags) { + masterTagObjects.put(tag, tag); + } + + // Rebuild the list of task tags using references from the master list + final Set commonTagReferences = new HashSet<>(); + for (Tag tag : taskTags) { + commonTagReferences.add(masterTagObjects.get(tag)); + } + event.setTags(new UniqueTagList(commonTagReferences)); + } + + public boolean removeTask(ReadOnlyFloatingTask key) throws UniqueFloatingTaskList.FloatingTaskNotFoundException { + if (tasks.remove(key)) { + return true; + } else { + throw new UniqueFloatingTaskList.FloatingTaskNotFoundException(); + } + } + + public boolean removeDeadline(ReadOnlyDeadline key) throws UniqueDeadlineList.DeadlineNotFoundException { + if (deadlines.remove(key)) { + return true; + } else { + throw new UniqueDeadlineList.DeadlineNotFoundException(); + } + } + +//// tag-level operations + + public void addTag(Tag t) throws UniqueTagList.DuplicateTagException { + tags.add(t); + } + +//// util methods + + @Override + public String toString() { + return tasks.getInternalList().size() + " tasks, " + tags.getInternalList().size() + " tags"; + // TODO: refine later + } + + @Override + public List getFloatingTaskList() { + return Collections.unmodifiableList(tasks.getInternalList()); + } + + public List getDeadlineList() { + return Collections.unmodifiableList(deadlines.getInternalList()); + } + + @Override + public List getEventList() { + return Collections.unmodifiableList(events.getInternalList()); + } + + @Override + public List getTagList() { + return Collections.unmodifiableList(tags.getInternalList()); + } + + @Override + public UniqueFloatingTaskList getUniqueFloatingTaskList() { + return this.tasks; + } + + + @Override + public UniqueDeadlineList getUniqueDeadlineList() { + return this.deadlines; + } + + @Override + public UniqueEventList getUniqueEventList() { + return this.events; + } + + @Override + public UniqueTagList getUniqueTagList() { + return this.tags; + } + + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof Malitio // instanceof handles nulls + && this.tasks.equals(((Malitio) other).tasks) + && this.deadlines.equals(((Malitio) other).deadlines) + && this.events.equals(((Malitio) other).events) + && this.tags.equals(((Malitio) other).tags)); + } + + @Override + public int hashCode() { + // use this method for custom fields hashing instead of implementing your own + return Objects.hash(tasks, deadlines, events, tags); + } + +} diff --git a/src/main/java/seedu/malitio/model/Model.java b/src/main/java/seedu/malitio/model/Model.java new file mode 100644 index 000000000000..4aac65909c31 --- /dev/null +++ b/src/main/java/seedu/malitio/model/Model.java @@ -0,0 +1,65 @@ +package seedu.malitio.model; + +import seedu.malitio.commons.core.UnmodifiableObservableList; +import seedu.malitio.model.task.Deadline; +import seedu.malitio.model.task.Event; +import seedu.malitio.model.task.FloatingTask; +import seedu.malitio.model.task.ReadOnlyDeadline; +import seedu.malitio.model.task.ReadOnlyEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.model.task.UniqueDeadlineList; +import seedu.malitio.model.task.UniqueEventList; +import seedu.malitio.model.task.UniqueFloatingTaskList; + +import java.util.Set; + +/** + * The API of the Model component. + */ +public interface Model { + /** Clears existing backing model and replaces with the provided new data. */ + void resetData(ReadOnlyMalitio newData); + + /** Returns Malitio */ + ReadOnlyMalitio getMalitio(); + + /** Deletes the given task. */ + void deleteTask(ReadOnlyFloatingTask target) throws UniqueFloatingTaskList.FloatingTaskNotFoundException; + + /** Adds the given floating task */ + void addFloatingTask(FloatingTask task) throws UniqueFloatingTaskList.DuplicateFloatingTaskException; + + /** Adds the given deadline*/ + void addDeadline(Deadline deadline) throws UniqueDeadlineList.DuplicateDeadlineException; + + /** Adds the given event*/ + void addEvent(Event event) throws UniqueEventList.DuplicateEventException; + + /** Returns the filtered floating task list as an {@code UnmodifiableObservableList} */ + UnmodifiableObservableList getFilteredFloatingTaskList(); + + /** Returns the filtered deadline list as an {@code UnmodifiableObservableList} */ + UnmodifiableObservableList getFilteredDeadlineList(); + + /** Returns the filtered deadline list as an {@code UnmodifiableObservableList} */ + UnmodifiableObservableList getFilteredEventList(); + + /** Updates the filter of the filtered floating task list to show all tasks */ + void updateFilteredTaskListToShowAll(); + + /** Updates the filter of the filtered deadlines to show all deadlines */ + void updateFilteredDeadlineListToShowAll(); + + /** Updates the filter of the filtered events to show all events */ + void updateFilteredEventListToShowAll(); + + /** Updates the filter of the filtered task list to filter by the given keywords*/ + void updateFilteredTaskList(Set keywords); + + /** Updates the filter of the filtered deadlines to filter by the given keywords*/ + void updateFilteredDeadlineList(Set keywords); + + /** Updates the filter of the filtered events to filter by the given keywords*/ + void updateFilteredEventList(Set keywords); + +} diff --git a/src/main/java/seedu/malitio/model/ModelManager.java b/src/main/java/seedu/malitio/model/ModelManager.java new file mode 100644 index 000000000000..c66532b0fa86 --- /dev/null +++ b/src/main/java/seedu/malitio/model/ModelManager.java @@ -0,0 +1,255 @@ +package seedu.malitio.model; + +import javafx.collections.transformation.FilteredList; +import seedu.malitio.commons.core.ComponentManager; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.core.UnmodifiableObservableList; +import seedu.malitio.commons.events.model.MalitioChangedEvent; +import seedu.malitio.commons.util.StringUtil; +import seedu.malitio.model.task.Deadline; +import seedu.malitio.model.task.Event; +import seedu.malitio.model.task.FloatingTask; +import seedu.malitio.model.task.ReadOnlyDeadline; +import seedu.malitio.model.task.ReadOnlyEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.model.task.UniqueDeadlineList.DuplicateDeadlineException; +import seedu.malitio.model.task.UniqueEventList.DuplicateEventException; +import seedu.malitio.model.task.UniqueFloatingTaskList.DuplicateFloatingTaskException; +import seedu.malitio.model.task.UniqueFloatingTaskList.FloatingTaskNotFoundException; + +import java.util.Set; +import java.util.logging.Logger; + +/** + * Represents the in-memory model of the malitio data. + * All changes to any model should be synchronized. + */ +public class ModelManager extends ComponentManager implements Model { + private static final Logger logger = LogsCenter.getLogger(ModelManager.class); + + private final Malitio malitio; + private final FilteredList filteredFloatingTasks; + private final FilteredList filteredDeadlines; + private final FilteredList filteredEvents; + + /** + * Initializes a ModelManager with the given Malitio + * Malitio and its variables should not be null + */ + public ModelManager(Malitio src, UserPrefs userPrefs) { + super(); + assert src != null; + assert userPrefs != null; + + logger.fine("Initializing with malitio: " + src + " and user prefs " + userPrefs); + + malitio = new Malitio(src); + filteredFloatingTasks = new FilteredList<>(malitio.getFloatingTasks()); + filteredDeadlines = new FilteredList<>(malitio.getDeadlines()); + filteredEvents = new FilteredList<>(malitio.getEvents()); + } + + public ModelManager() { + this(new Malitio(), new UserPrefs()); + } + + public ModelManager(ReadOnlyMalitio initialData, UserPrefs userPrefs) { + malitio = new Malitio(initialData); + filteredFloatingTasks = new FilteredList<>(malitio.getFloatingTasks()); + filteredDeadlines = new FilteredList<>(malitio.getDeadlines()); + filteredEvents = new FilteredList<>(malitio.getEvents()); + } + + @Override + public void resetData(ReadOnlyMalitio newData) { + malitio.resetData(newData); + indicatemalitioChanged(); + } + + @Override + public ReadOnlyMalitio getMalitio() { + return malitio; + } + + /** Raises an event to indicate the model has changed */ + private void indicatemalitioChanged() { + raise(new MalitioChangedEvent(malitio)); + } + + @Override + public synchronized void deleteTask(ReadOnlyFloatingTask target) throws FloatingTaskNotFoundException { + malitio.removeTask(target); + indicatemalitioChanged(); + } + + @Override + public void addFloatingTask(FloatingTask task) throws DuplicateFloatingTaskException { + malitio.addFloatingTask(task); + updateFilteredTaskListToShowAll(); + indicatemalitioChanged(); + } + + @Override + public void addDeadline(Deadline deadline) throws DuplicateDeadlineException { + malitio.addDeadline(deadline); + updateFilteredDeadlineListToShowAll(); + indicatemalitioChanged(); + + } + + @Override + public void addEvent(Event event) throws DuplicateEventException { + malitio.addEvent(event); + updateFilteredDeadlineListToShowAll(); + indicatemalitioChanged(); + + } + + //=========== Filtered Task List Accessors =============================================================== + + @Override + public UnmodifiableObservableList getFilteredFloatingTaskList() { + return new UnmodifiableObservableList<>(filteredFloatingTasks); + } + + @Override + public UnmodifiableObservableList getFilteredDeadlineList() { + return new UnmodifiableObservableList<>(filteredDeadlines); + } + + @Override + public UnmodifiableObservableList getFilteredEventList() { + return new UnmodifiableObservableList<>(filteredEvents); + } + + @Override + public void updateFilteredTaskListToShowAll() { + filteredFloatingTasks.setPredicate(null); + } + + @Override + public void updateFilteredDeadlineListToShowAll() { + filteredDeadlines.setPredicate(null); + } + + @Override + public void updateFilteredEventListToShowAll() { + filteredEvents.setPredicate(null); + } + + @Override + public void updateFilteredTaskList(Set keywords){ + updateFilteredTaskList(new PredicateExpression(new NameQualifier(keywords))); + } + + private void updateFilteredTaskList(Expression expression) { + filteredFloatingTasks.setPredicate(expression::satisfies); + } + + @Override + public void updateFilteredDeadlineList(Set keywords){ + updateFilteredDeadlines(new PredicateExpression(new NameQualifier(keywords))); + } + + private void updateFilteredDeadlines(Expression expression) { + filteredDeadlines.setPredicate(expression::satisfies); + } + + @Override + public void updateFilteredEventList(Set keywords){ + updateFilteredEvents(new PredicateExpression(new NameQualifier(keywords))); + } + + private void updateFilteredEvents(Expression expression) { + filteredEvents.setPredicate(expression::satisfies); + } + + //========== Inner classes/interfaces used for filtering ================================================== + + interface Expression { + boolean satisfies(ReadOnlyFloatingTask task); + boolean satisfies(ReadOnlyDeadline deadline); + boolean satisfies(ReadOnlyEvent event); + String toString(); + } + + private class PredicateExpression implements Expression { + + private final Qualifier qualifier; + + PredicateExpression(Qualifier qualifier) { + this.qualifier = qualifier; + } + + @Override + public boolean satisfies(ReadOnlyFloatingTask task) { + return qualifier.run(task); + } + + @Override + public boolean satisfies(ReadOnlyDeadline deadline) { + return qualifier.run(deadline); + } + + @Override + public boolean satisfies(ReadOnlyEvent event) { + return qualifier.run(event); + } + + @Override + public String toString() { + return qualifier.toString(); + } + } + + interface Qualifier { + boolean run(ReadOnlyFloatingTask task); + boolean run(ReadOnlyDeadline schedule); + boolean run(ReadOnlyEvent event); + String toString(); + } + + private class NameQualifier implements Qualifier { + private Set nameKeyWords; + + NameQualifier(Set nameKeyWords) { + this.nameKeyWords = nameKeyWords; + } + + @Override + public boolean run(ReadOnlyFloatingTask task) { + return nameKeyWords.stream() + .filter(keyword -> StringUtil.containsIgnoreCase(task.getName().fullName, keyword)) + .findAny() + .isPresent(); + } + + @Override + public boolean run(ReadOnlyDeadline deadline) { + return nameKeyWords.stream() + .filter(keyword -> StringUtil.containsIgnoreCase(deadline.getName().fullName + + " " + deadline.getDue().toString(), + keyword)) + .findAny() + .isPresent(); + } + + @Override + public boolean run(ReadOnlyEvent event) { + return nameKeyWords.stream() + .filter(keyword -> StringUtil.containsIgnoreCase(event.getName().fullName + + " " + event.getStart().toString() + + " " + event.getEnd().toString(), + keyword)) + .findAny() + .isPresent(); + } + + + @Override + public String toString() { + return "name=" + String.join(", ", nameKeyWords); + } + } + +} diff --git a/src/main/java/seedu/malitio/model/ReadOnlyMalitio.java b/src/main/java/seedu/malitio/model/ReadOnlyMalitio.java new file mode 100644 index 000000000000..ba65f92c92e8 --- /dev/null +++ b/src/main/java/seedu/malitio/model/ReadOnlyMalitio.java @@ -0,0 +1,48 @@ +package seedu.malitio.model; + + +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.ReadOnlyDeadline; +import seedu.malitio.model.task.ReadOnlyEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.model.task.UniqueDeadlineList; +import seedu.malitio.model.task.UniqueEventList; +import seedu.malitio.model.task.UniqueFloatingTaskList; + +import java.util.List; + +/** + * Unmodifiable view of an malitio + */ +public interface ReadOnlyMalitio { + + UniqueTagList getUniqueTagList(); + + UniqueFloatingTaskList getUniqueFloatingTaskList(); + + UniqueDeadlineList getUniqueDeadlineList(); + + UniqueEventList getUniqueEventList(); + + /** + * Returns an unmodifiable view of tasks list + */ + List getFloatingTaskList(); + + /** + * Returns an unmodifiable view of deadlines list + */ + List getDeadlineList(); + + /** + * Returns an unmodifiable view of deadlines list + */ + List getEventList(); + + /** + * Returns an unmodifiable view of tags list + */ + List getTagList(); + +} diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/seedu/malitio/model/UserPrefs.java similarity index 93% rename from src/main/java/seedu/address/model/UserPrefs.java rename to src/main/java/seedu/malitio/model/UserPrefs.java index da9c8037f495..88f539cd247e 100644 --- a/src/main/java/seedu/address/model/UserPrefs.java +++ b/src/main/java/seedu/malitio/model/UserPrefs.java @@ -1,9 +1,9 @@ -package seedu.address.model; - -import seedu.address.commons.core.GuiSettings; +package seedu.malitio.model; import java.util.Objects; +import seedu.malitio.commons.core.GuiSettings; + /** * Represents User's preferences. */ diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/malitio/model/tag/Tag.java similarity index 91% rename from src/main/java/seedu/address/model/tag/Tag.java rename to src/main/java/seedu/malitio/model/tag/Tag.java index 5bcffdb5ddf1..3468d63c1f1d 100644 --- a/src/main/java/seedu/address/model/tag/Tag.java +++ b/src/main/java/seedu/malitio/model/tag/Tag.java @@ -1,10 +1,10 @@ -package seedu.address.model.tag; +package seedu.malitio.model.tag; -import seedu.address.commons.exceptions.IllegalValueException; +import seedu.malitio.commons.exceptions.IllegalValueException; /** - * Represents a Tag in the address book. + * Represents a Tag in the malitio. * Guarantees: immutable; name is valid as declared in {@link #isValidTagName(String)} */ public class Tag { diff --git a/src/main/java/seedu/address/model/tag/UniqueTagList.java b/src/main/java/seedu/malitio/model/tag/UniqueTagList.java similarity index 96% rename from src/main/java/seedu/address/model/tag/UniqueTagList.java rename to src/main/java/seedu/malitio/model/tag/UniqueTagList.java index 76fb7ff3dc5d..c1cddb6967fe 100644 --- a/src/main/java/seedu/address/model/tag/UniqueTagList.java +++ b/src/main/java/seedu/malitio/model/tag/UniqueTagList.java @@ -1,9 +1,9 @@ -package seedu.address.model.tag; +package seedu.malitio.model.tag; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import seedu.address.commons.util.CollectionUtil; -import seedu.address.commons.exceptions.DuplicateDataException; +import seedu.malitio.commons.exceptions.DuplicateDataException; +import seedu.malitio.commons.util.CollectionUtil; import java.util.*; diff --git a/src/main/java/seedu/malitio/model/task/DateTime.java b/src/main/java/seedu/malitio/model/task/DateTime.java new file mode 100644 index 000000000000..135ef5417d87 --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/DateTime.java @@ -0,0 +1,55 @@ +package seedu.malitio.model.task; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import seedu.malitio.commons.exceptions.IllegalValueException; + +/** + * Represents a date and time of an event or deadline + */ +public class DateTime { + public static final String MESSAGE_DATETIME_CONSTRAINTS = "Invalid date and time format!"; + + private Date date; + + private static DateFormat df = new SimpleDateFormat("ddMMyyyy HHmm"); + + /** + * Converts the string that contains date information into Date + * + * @throws IllegalValueException if the format of date is incorrect + */ + public DateTime(String date) throws IllegalValueException { + if(!isValidDateTime(date)) { + throw new IllegalValueException(MESSAGE_DATETIME_CONSTRAINTS); + } + try { + this.date = df.parse(date); + } catch (ParseException e) { + e.printStackTrace(); + } + + } + + /** + * Checks the validity of the input string as date and time + */ + private static boolean isValidDateTime(String args) { + df.setLenient(false); + try { + df.parse(args); + return true; + } catch (ParseException e) { + e.printStackTrace(); + } + return false; + } + + public String toString() { + String newDateString = df.format(date); + return newDateString; + } +} diff --git a/src/main/java/seedu/malitio/model/task/Deadline.java b/src/main/java/seedu/malitio/model/task/Deadline.java new file mode 100644 index 000000000000..2935c442e32b --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/Deadline.java @@ -0,0 +1,68 @@ +package seedu.malitio.model.task; + +import java.util.Objects; + +import seedu.malitio.model.tag.UniqueTagList; + +public class Deadline implements ReadOnlyDeadline{ + + private Name name; + private DateTime due; + private UniqueTagList tags; + + + public Deadline(Name name, DateTime due, UniqueTagList tags) { + this.name = name; + this.due = due; + this.tags = new UniqueTagList(tags); // protect internal tags from changes in the arg list + } + + /** + * Copy constructor. + */ + public Deadline(ReadOnlyDeadline source) { + this(source.getName(), source.getDue(), source.getTags()); + } + + + @Override + public Name getName() { + return name; + } + + @Override + public DateTime getDue() { + return due; + } + + @Override + public UniqueTagList getTags() { + return new UniqueTagList(tags); + } + + /** + * Replaces this deadline's tags with the tags in the argument tag list. + */ + public void setTags(UniqueTagList replacement) { + tags.setTags(replacement); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof ReadOnlyDeadline// instanceof handles nulls + && this.isSameStateAs((ReadOnlyDeadline) other)); + } + + @Override + public int hashCode() { + // use this method for custom fields hashing instead of implementing your own + return Objects.hash(name, due, tags); + } + + @Override + public String toString() { + return getAsText(); + } + +} diff --git a/src/main/java/seedu/malitio/model/task/Event.java b/src/main/java/seedu/malitio/model/task/Event.java new file mode 100644 index 000000000000..278cfb311e67 --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/Event.java @@ -0,0 +1,74 @@ +package seedu.malitio.model.task; + +import java.util.Objects; + +import seedu.malitio.model.tag.UniqueTagList; + +public class Event implements ReadOnlyEvent { + private Name name; + private DateTime start; + private DateTime end; + private UniqueTagList tags; + + + public Event(Name name, DateTime start, DateTime end, UniqueTagList tags) { + this.name=name; + this.start = start; + this.end = end; + this.tags = new UniqueTagList(tags); // protect internal tags from changes in the arg list + } + + /** + * Copy constructor. + */ + public Event(ReadOnlyEvent source) { + this(source.getName(), source.getStart(), source.getEnd(), source.getTags()); + } + + @Override + public Name getName() { + return name; + } + + @Override + public DateTime getStart() { + return start; + } + + @Override + public DateTime getEnd() { + return end; + } + + + @Override + public UniqueTagList getTags() { + return new UniqueTagList(tags); + } + + /** + * Replaces this event's tags with the tags in the argument tag list. + */ + public void setTags(UniqueTagList replacement) { + tags.setTags(replacement); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof ReadOnlyEvent// instanceof handles nulls + && this.isSameStateAs((ReadOnlyEvent) other)); + } + + @Override + public int hashCode() { + // use this method for custom fields hashing instead of implementing your own + return Objects.hash(name, start, end, tags); + } + + @Override + public String toString() { + return getAsText(); + } + +} diff --git a/src/main/java/seedu/malitio/model/task/FloatingTask.java b/src/main/java/seedu/malitio/model/task/FloatingTask.java new file mode 100644 index 000000000000..6582621f74c3 --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/FloatingTask.java @@ -0,0 +1,66 @@ +package seedu.malitio.model.task; + +import java.util.Objects; + +import seedu.malitio.commons.util.CollectionUtil; +import seedu.malitio.model.tag.UniqueTagList; + +public class FloatingTask implements ReadOnlyFloatingTask { + + private Name name; + + private UniqueTagList tags; + + /** + * Constructor for tasks. + */ + public FloatingTask(Name name, UniqueTagList tags) { + assert !CollectionUtil.isAnyNull(name, tags); + this.name = name; + this.tags = new UniqueTagList(tags); // protect internal tags from changes in the arg list + } + + /** + * Copy constructor. + */ + public FloatingTask(ReadOnlyFloatingTask source) { + this(source.getName(), source.getTags()); + } + + @Override + public Name getName() { + return name; + } + + + @Override + public UniqueTagList getTags() { + return new UniqueTagList(tags); + } + + /** + * Replaces this task's tags with the tags in the argument tag list. + */ + public void setTags(UniqueTagList replacement) { + tags.setTags(replacement); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof ReadOnlyFloatingTask // instanceof handles nulls + && this.isSameStateAs((ReadOnlyFloatingTask) other)); + } + + @Override + public int hashCode() { + // use this method for custom fields hashing instead of implementing your own + return Objects.hash(name, tags); + } + + @Override + public String toString() { + return getAsText(); + } + +} diff --git a/src/main/java/seedu/address/model/person/Name.java b/src/main/java/seedu/malitio/model/task/Name.java similarity index 73% rename from src/main/java/seedu/address/model/person/Name.java rename to src/main/java/seedu/malitio/model/task/Name.java index 4f30033e70fe..13a6fd2d933f 100644 --- a/src/main/java/seedu/address/model/person/Name.java +++ b/src/main/java/seedu/malitio/model/task/Name.java @@ -1,15 +1,15 @@ -package seedu.address.model.person; +package seedu.malitio.model.task; -import seedu.address.commons.exceptions.IllegalValueException; +import seedu.malitio.commons.exceptions.IllegalValueException; /** - * Represents a Person's name in the address book. + * Represents a Task's name in the Malitio. * Guarantees: immutable; is valid as declared in {@link #isValidName(String)} */ public class Name { - public static final String MESSAGE_NAME_CONSTRAINTS = "Person names should be spaces or alphanumeric characters"; - public static final String NAME_VALIDATION_REGEX = "[\\p{Alnum} ]+"; + public static final String MESSAGE_NAME_CONSTRAINTS = "Task names should not inculde forward slash ('/')"; + public static final String NAME_VALIDATION_REGEX = ".+"; public final String fullName; @@ -28,7 +28,7 @@ public Name(String name) throws IllegalValueException { } /** - * Returns true if a given string is a valid person name. + * Returns true if a given string is a valid task name. */ public static boolean isValidName(String test) { return test.matches(NAME_VALIDATION_REGEX); diff --git a/src/main/java/seedu/malitio/model/task/ReadOnlyDeadline.java b/src/main/java/seedu/malitio/model/task/ReadOnlyDeadline.java new file mode 100644 index 000000000000..e9bb0171a3ed --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/ReadOnlyDeadline.java @@ -0,0 +1,57 @@ +package seedu.malitio.model.task; +import seedu.malitio.model.tag.UniqueTagList; + +/** + * A read-only immutable interface for a Deadline in Malitio. + * Implementations should guarantee: details are present and not null, field values are validated. + */ + +public interface ReadOnlyDeadline { + + Name getName(); + DateTime getDue(); + + /** + * The returned TagList is a deep copy of the internal TagList, + * changes on the returned list will not affect the task's internal tags. + */ + UniqueTagList getTags(); + + /** + * Returns true if both have the same state. (interfaces cannot override .equals) + */ + default boolean isSameStateAs(ReadOnlyDeadline other) { + return other == this // short circuit if same object + || (other != null // this is first to avoid NPE below + && other.getName().equals(this.getName()) + && other.getDue().equals(this.getDue()) //state checks here onwards + ); + } + + /** + * Formats the task as text, showing all contact details. + */ + default String getAsText() { + final StringBuilder builder = new StringBuilder(); + builder.append(getName()) + .append(getDue()) + .append(" Tags: "); + getTags().forEach(builder::append); + return builder.toString(); + } + + /** + * Returns a string representation of this Task's tags + */ + default String tagsString() { + final StringBuffer buffer = new StringBuffer(); + final String separator = ", "; + getTags().forEach(tag -> buffer.append(tag).append(separator)); + if (buffer.length() == 0) { + return ""; + } else { + return buffer.substring(0, buffer.length() - separator.length()); + } + } +} + diff --git a/src/main/java/seedu/malitio/model/task/ReadOnlyEvent.java b/src/main/java/seedu/malitio/model/task/ReadOnlyEvent.java new file mode 100644 index 000000000000..c6aa685be663 --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/ReadOnlyEvent.java @@ -0,0 +1,60 @@ +package seedu.malitio.model.task; +import seedu.malitio.model.tag.UniqueTagList; + +/** + * A read-only immutable interface for a Deadline in Malitio. + * Implementations should guarantee: details are present and not null, field values are validated. + */ + +public interface ReadOnlyEvent { + + Name getName(); + DateTime getStart(); + DateTime getEnd(); + + /** + * The returned TagList is a deep copy of the internal TagList, + * changes on the returned list will not affect the event's internal tags. + */ + UniqueTagList getTags(); + + /** + * Returns true if both have the same state. (interfaces cannot override .equals) + */ + default boolean isSameStateAs(ReadOnlyEvent other) { + return other == this // short circuit if same object + || (other != null // this is first to avoid NPE below + && other.getName().equals(this.getName()) + && other.getStart().equals(this.getStart()) + && other.getStart().equals(this.getEnd())//state checks here onwards + ); + } + + /** + * Formats the event as text, showing all contact details. + */ + default String getAsText() { + final StringBuilder builder = new StringBuilder(); + builder.append(getName()) + .append(getStart()) + .append(getEnd()) + .append(" Tags: "); + getTags().forEach(builder::append); + return builder.toString(); + } + + /** + * Returns a string representation of this Event's tags + */ + default String tagsString() { + final StringBuffer buffer = new StringBuffer(); + final String separator = ", "; + getTags().forEach(tag -> buffer.append(tag).append(separator)); + if (buffer.length() == 0) { + return ""; + } else { + return buffer.substring(0, buffer.length() - separator.length()); + } + } +} + diff --git a/src/main/java/seedu/address/model/person/ReadOnlyPerson.java b/src/main/java/seedu/malitio/model/task/ReadOnlyFloatingTask.java similarity index 57% rename from src/main/java/seedu/address/model/person/ReadOnlyPerson.java rename to src/main/java/seedu/malitio/model/task/ReadOnlyFloatingTask.java index d45be4b5fe36..272fa3ccc553 100644 --- a/src/main/java/seedu/address/model/person/ReadOnlyPerson.java +++ b/src/main/java/seedu/malitio/model/task/ReadOnlyFloatingTask.java @@ -1,55 +1,45 @@ -package seedu.address.model.person; +package seedu.malitio.model.task; -import seedu.address.model.tag.UniqueTagList; +import seedu.malitio.model.tag.UniqueTagList; /** - * A read-only immutable interface for a Person in the addressbook. + * A read-only immutable interface for a Task in Malitio. * Implementations should guarantee: details are present and not null, field values are validated. */ -public interface ReadOnlyPerson { +public interface ReadOnlyFloatingTask { Name getName(); - Phone getPhone(); - Email getEmail(); - Address getAddress(); + /** * The returned TagList is a deep copy of the internal TagList, - * changes on the returned list will not affect the person's internal tags. + * changes on the returned list will not affect the task's internal tags. */ UniqueTagList getTags(); /** * Returns true if both have the same state. (interfaces cannot override .equals) */ - default boolean isSameStateAs(ReadOnlyPerson other) { + default boolean isSameStateAs(ReadOnlyFloatingTask other) { return other == this // short circuit if same object || (other != null // this is first to avoid NPE below && other.getName().equals(this.getName()) // state checks here onwards - && other.getPhone().equals(this.getPhone()) - && other.getEmail().equals(this.getEmail()) - && other.getAddress().equals(this.getAddress())); +); } /** - * Formats the person as text, showing all contact details. + * Formats the task as text, showing all contact details. */ default String getAsText() { final StringBuilder builder = new StringBuilder(); builder.append(getName()) - .append(" Phone: ") - .append(getPhone()) - .append(" Email: ") - .append(getEmail()) - .append(" Address: ") - .append(getAddress()) .append(" Tags: "); getTags().forEach(builder::append); return builder.toString(); } /** - * Returns a string representation of this Person's tags + * Returns a string representation of this Task's tags */ default String tagsString() { final StringBuffer buffer = new StringBuffer(); diff --git a/src/main/java/seedu/malitio/model/task/UniqueDeadlineList.java b/src/main/java/seedu/malitio/model/task/UniqueDeadlineList.java new file mode 100644 index 000000000000..4b44e4ff5eee --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/UniqueDeadlineList.java @@ -0,0 +1,98 @@ +package seedu.malitio.model.task; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.malitio.commons.exceptions.DuplicateDataException; +import seedu.malitio.commons.util.CollectionUtil; + +import java.util.*; + +/** + * A list of tasks that enforces uniqueness between its elements and does not allow nulls. + * + * Supports a minimal set of list operations. + * + * @see Task#equals(Object) + * @see CollectionUtil#elementsAreUnique(Collection) + */ +public class UniqueDeadlineList implements Iterable { + + /** + * Signals that an operation would have violated the 'no duplicates' property of the list. + */ + public static class DuplicateDeadlineException extends DuplicateDataException { + protected DuplicateDeadlineException() { + super("Operation would result in duplicate deadlines"); + } + } + + /** + * Signals that an operation targeting a specified task in the list would fail because + * there is no such matching task in the list. + */ + public static class DeadlineNotFoundException extends Exception {} + + private final ObservableList internalList = FXCollections.observableArrayList(); + + /** + * Constructs empty TaskList. + */ + public UniqueDeadlineList() {} + + /** + * Returns true if the list contains an equivalent task as the given argument. + */ + public boolean contains(ReadOnlyDeadline toCheck) { + assert toCheck != null; + return internalList.contains(toCheck); + } + + /** + * Adds a task to the list. + * + * @throws DuplicateFloatingTaskException if the task to add is a duplicate of an existing task in the list. + */ + public void add(Deadline toAdd) throws DuplicateDeadlineException { + assert toAdd != null; + if (contains(toAdd)) { + throw new DuplicateDeadlineException(); + } + internalList.add(toAdd); + } + + /** + * Removes the equivalent schedule from the list. + * + * @throws DeadlineNotFoundException if no such deadline could be found in the list. + */ + public boolean remove(ReadOnlyDeadline toRemove) throws DeadlineNotFoundException { + assert toRemove != null; + final boolean deadlineFoundAndDeleted = internalList.remove(toRemove); + if (!deadlineFoundAndDeleted) { + throw new DeadlineNotFoundException(); + } + return deadlineFoundAndDeleted; + } + + public ObservableList getInternalList() { + return internalList; + } + + @Override + public Iterator iterator() { + return internalList.iterator(); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof UniqueDeadlineList // instanceof handles nulls + && this.internalList.equals( + ((UniqueDeadlineList) other).internalList)); + } + + @Override + public int hashCode() { + return internalList.hashCode(); + } +} \ No newline at end of file diff --git a/src/main/java/seedu/malitio/model/task/UniqueEventList.java b/src/main/java/seedu/malitio/model/task/UniqueEventList.java new file mode 100644 index 000000000000..8f275a080b31 --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/UniqueEventList.java @@ -0,0 +1,99 @@ +package seedu.malitio.model.task; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.malitio.commons.exceptions.DuplicateDataException; +import seedu.malitio.commons.util.CollectionUtil; + +import java.util.*; + +/** + * A list of tasks that enforces uniqueness between its elements and does not allow nulls. + * + * Supports a minimal set of list operations. + * + * @see Task#equals(Object) + * @see CollectionUtil#elementsAreUnique(Collection) + */ +public class UniqueEventList implements Iterable { + + /** + * Signals that an operation would have violated the 'no duplicates' property of the list. + */ + public static class DuplicateEventException extends DuplicateDataException { + protected DuplicateEventException() { + super("Operation would result in duplicate deadlines"); + } + } + + /** + * Signals that an operation targeting a specified task in the list would fail because + * there is no such matching task in the list. + */ + public static class EventNotFoundException extends Exception {} + + private final ObservableList internalList = FXCollections.observableArrayList(); + + /** + * Constructs empty EventList. + */ + public UniqueEventList() {} + + /** + * Returns true if the list contains an equivalent event as the given argument. + */ + public boolean contains(ReadOnlyEvent toCheck) { + assert toCheck != null; + return internalList.contains(toCheck); + } + + /** + * Adds a task to the list. + * + * @throws DuplicateEventException if the event to add is a duplicate of an existing event in the list. + */ + public void add(Event toAdd) throws DuplicateEventException { + assert toAdd != null; + if (contains(toAdd)) { + throw new DuplicateEventException(); + } + internalList.add(toAdd); + } + + /** + * Removes the equivalent schedule from the list. + * + * @throws FloatingTaskNotFoundException if no such task could be found in the list. + */ + public boolean remove(ReadOnlyEvent toRemove) throws EventNotFoundException { + assert toRemove != null; + final boolean eventFoundAndDeleted = internalList.remove(toRemove); + if (!eventFoundAndDeleted) { + throw new EventNotFoundException(); + } + return eventFoundAndDeleted; + } + + public ObservableList getInternalList() { + return internalList; + } + + @Override + public Iterator iterator() { + return internalList.iterator(); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof UniqueEventList // instanceof handles nulls + && this.internalList.equals( + ((UniqueEventList) other).internalList)); + } + + @Override + public int hashCode() { + return internalList.hashCode(); + } +} + diff --git a/src/main/java/seedu/malitio/model/task/UniqueFloatingTaskList.java b/src/main/java/seedu/malitio/model/task/UniqueFloatingTaskList.java new file mode 100644 index 000000000000..01720c3530bd --- /dev/null +++ b/src/main/java/seedu/malitio/model/task/UniqueFloatingTaskList.java @@ -0,0 +1,98 @@ +package seedu.malitio.model.task; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.malitio.commons.exceptions.DuplicateDataException; +import seedu.malitio.commons.util.CollectionUtil; + +import java.util.*; + +/** + * A list of tasks that enforces uniqueness between its elements and does not allow nulls. + * + * Supports a minimal set of list operations. + * + * @see Task#equals(Object) + * @see CollectionUtil#elementsAreUnique(Collection) + */ +public class UniqueFloatingTaskList implements Iterable { + + /** + * Signals that an operation would have violated the 'no duplicates' property of the list. + */ + public static class DuplicateFloatingTaskException extends DuplicateDataException { + protected DuplicateFloatingTaskException() { + super("Operation would result in duplicate floating tasks"); + } + } + + /** + * Signals that an operation targeting a specified task in the list would fail because + * there is no such matching task in the list. + */ + public static class FloatingTaskNotFoundException extends Exception {} + + private final ObservableList internalList = FXCollections.observableArrayList(); + + /** + * Constructs empty TaskList. + */ + public UniqueFloatingTaskList() {} + + /** + * Returns true if the list contains an equivalent task as the given argument. + */ + public boolean contains(ReadOnlyFloatingTask toCheck) { + assert toCheck != null; + return internalList.contains(toCheck); + } + + /** + * Adds a task to the list. + * + * @throws DuplicateFloatingTaskException if the task to add is a duplicate of an existing task in the list. + */ + public void add(FloatingTask toAdd) throws DuplicateFloatingTaskException { + assert toAdd != null; + if (contains(toAdd)) { + throw new DuplicateFloatingTaskException(); + } + internalList.add(toAdd); + } + + /** + * Removes the equivalent task from the list. + * + * @throws FloatingTaskNotFoundException if no such task could be found in the list. + */ + public boolean remove(ReadOnlyFloatingTask toRemove) throws FloatingTaskNotFoundException { + assert toRemove != null; + final boolean taskFoundAndDeleted = internalList.remove(toRemove); + if (!taskFoundAndDeleted) { + throw new FloatingTaskNotFoundException(); + } + return taskFoundAndDeleted; + } + + public ObservableList getInternalList() { + return internalList; + } + + @Override + public Iterator iterator() { + return internalList.iterator(); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof UniqueFloatingTaskList // instanceof handles nulls + && this.internalList.equals( + ((UniqueFloatingTaskList) other).internalList)); + } + + @Override + public int hashCode() { + return internalList.hashCode(); + } +} diff --git a/src/main/java/seedu/address/storage/JsonUserPrefsStorage.java b/src/main/java/seedu/malitio/storage/JsonUserPrefsStorage.java similarity index 90% rename from src/main/java/seedu/address/storage/JsonUserPrefsStorage.java rename to src/main/java/seedu/malitio/storage/JsonUserPrefsStorage.java index 1efa8288e4f6..3e2b5322fd66 100644 --- a/src/main/java/seedu/address/storage/JsonUserPrefsStorage.java +++ b/src/main/java/seedu/malitio/storage/JsonUserPrefsStorage.java @@ -1,9 +1,9 @@ -package seedu.address.storage; +package seedu.malitio.storage; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.commons.util.FileUtil; -import seedu.address.model.UserPrefs; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.commons.util.FileUtil; +import seedu.malitio.model.UserPrefs; import java.io.File; import java.io.IOException; diff --git a/src/main/java/seedu/malitio/storage/MalitioStorage.java b/src/main/java/seedu/malitio/storage/MalitioStorage.java new file mode 100644 index 000000000000..dad9351d9418 --- /dev/null +++ b/src/main/java/seedu/malitio/storage/MalitioStorage.java @@ -0,0 +1,44 @@ +package seedu.malitio.storage; + +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.model.ReadOnlyMalitio; + +import java.io.IOException; +import java.util.Optional; + +/** + * Represents a storage for {@link seedu.malitio.model.Malitio}. + */ +public interface MalitioStorage { + + /** + * Returns the file path of the data file. + */ + String getMalitioFilePath(); + + /** + * Returns malitio data as a {@link ReadOnlyMalitio}. + * Returns {@code Optional.empty()} if storage file is not found. + * @throws DataConversionException if the data in storage is not in the expected format. + * @throws IOException if there was any problem when reading from the storage. + */ + Optional readMalitio() throws DataConversionException, IOException; + + /** + * @see #getMalitioFilePath() + */ + Optional readMalitio(String filePath) throws DataConversionException, IOException; + + /** + * Saves the given {@link ReadOnlyMalitio} to the storage. + * @param malitio cannot be null. + * @throws IOException if there was any problem writing to the file. + */ + void savemalitio(ReadOnlyMalitio malitio) throws IOException; + + /** + * @see #savemalitio(ReadOnlyMalitio) + */ + void savemalitio(ReadOnlyMalitio malitio, String filePath) throws IOException; + +} diff --git a/src/main/java/seedu/malitio/storage/Storage.java b/src/main/java/seedu/malitio/storage/Storage.java new file mode 100644 index 000000000000..525bc16ae44e --- /dev/null +++ b/src/main/java/seedu/malitio/storage/Storage.java @@ -0,0 +1,39 @@ +package seedu.malitio.storage; + +import seedu.malitio.commons.events.model.MalitioChangedEvent; +import seedu.malitio.commons.events.storage.DataSavingExceptionEvent; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.model.ReadOnlyMalitio; +import seedu.malitio.model.UserPrefs; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Optional; + +/** + * API of the Storage component + */ +public interface Storage extends MalitioStorage, UserPrefsStorage { + + @Override + Optional readUserPrefs() throws DataConversionException, IOException; + + @Override + void saveUserPrefs(UserPrefs userPrefs) throws IOException; + + @Override + String getMalitioFilePath(); + + @Override + Optional readMalitio() throws DataConversionException, IOException; + + @Override + void savemalitio(ReadOnlyMalitio malitio) throws IOException; + + /** + * Saves the current version of the malitio to the hard disk. + * Creates the data file if it is missing. + * Raises {@link DataSavingExceptionEvent} if there was an error during saving. + */ + void handlemalitioChangedEvent(MalitioChangedEvent abce); +} diff --git a/src/main/java/seedu/malitio/storage/StorageManager.java b/src/main/java/seedu/malitio/storage/StorageManager.java new file mode 100644 index 000000000000..d2a850d2a6bf --- /dev/null +++ b/src/main/java/seedu/malitio/storage/StorageManager.java @@ -0,0 +1,92 @@ +package seedu.malitio.storage; + +import com.google.common.eventbus.Subscribe; + +import seedu.malitio.commons.core.ComponentManager; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.events.model.MalitioChangedEvent; +import seedu.malitio.commons.events.storage.DataSavingExceptionEvent; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.model.ReadOnlyMalitio; +import seedu.malitio.model.UserPrefs; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Optional; +import java.util.logging.Logger; + +/** + * Manages storage of Malitio data in local storage. + */ +public class StorageManager extends ComponentManager implements Storage { + + private static final Logger logger = LogsCenter.getLogger(StorageManager.class); + private MalitioStorage malitioStorage; + private UserPrefsStorage userPrefsStorage; + + + public StorageManager(MalitioStorage malitioStorage, UserPrefsStorage userPrefsStorage) { + super(); + this.malitioStorage = malitioStorage; + this.userPrefsStorage = userPrefsStorage; + } + + public StorageManager(String malitioFilePath, String userPrefsFilePath) { + this(new XmlMalitioStorage(malitioFilePath), new JsonUserPrefsStorage(userPrefsFilePath)); + } + + // ================ UserPrefs methods ============================== + + @Override + public Optional readUserPrefs() throws DataConversionException, IOException { + return userPrefsStorage.readUserPrefs(); + } + + @Override + public void saveUserPrefs(UserPrefs userPrefs) throws IOException { + userPrefsStorage.saveUserPrefs(userPrefs); + } + + + // ================ malitio methods ============================== + + @Override + public String getMalitioFilePath() { + return malitioStorage.getMalitioFilePath(); + } + + @Override + public Optional readMalitio() throws DataConversionException, IOException { + return readMalitio(malitioStorage.getMalitioFilePath()); + } + + @Override + public Optional readMalitio(String filePath) throws DataConversionException, IOException { + logger.fine("Attempting to read data from file: " + filePath); + return malitioStorage.readMalitio(filePath); + } + + @Override + public void savemalitio(ReadOnlyMalitio malitio) throws IOException { + savemalitio(malitio, malitioStorage.getMalitioFilePath()); + } + + @Override + public void savemalitio(ReadOnlyMalitio malitio, String filePath) throws IOException { + logger.fine("Attempting to write to data file: " + filePath); + malitioStorage.savemalitio(malitio, filePath); + } + + + @Override + @Subscribe + public void handlemalitioChangedEvent(MalitioChangedEvent event) { + logger.info(LogsCenter.getEventHandlingLogMessage(event, "Local data changed, saving to file")); + try { + savemalitio(event.data); + } catch (IOException e) { + raise(new DataSavingExceptionEvent(e)); + } + } + +} diff --git a/src/main/java/seedu/address/storage/UserPrefsStorage.java b/src/main/java/seedu/malitio/storage/UserPrefsStorage.java similarity index 73% rename from src/main/java/seedu/address/storage/UserPrefsStorage.java rename to src/main/java/seedu/malitio/storage/UserPrefsStorage.java index ad2dc935187c..df3e88aaeb36 100644 --- a/src/main/java/seedu/address/storage/UserPrefsStorage.java +++ b/src/main/java/seedu/malitio/storage/UserPrefsStorage.java @@ -1,13 +1,13 @@ -package seedu.address.storage; +package seedu.malitio.storage; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.model.UserPrefs; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.model.UserPrefs; import java.io.IOException; import java.util.Optional; /** - * Represents a storage for {@link seedu.address.model.UserPrefs}. + * Represents a storage for {@link seedu.malitio.model.UserPrefs}. */ public interface UserPrefsStorage { @@ -20,7 +20,7 @@ public interface UserPrefsStorage { Optional readUserPrefs() throws DataConversionException, IOException; /** - * Saves the given {@link seedu.address.model.UserPrefs} to the storage. + * Saves the given {@link seedu.malitio.model.UserPrefs} to the storage. * @param userPrefs cannot be null. * @throws IOException if there was any problem writing to the file. */ diff --git a/src/main/java/seedu/malitio/storage/XmlAdaptedDeadline.java b/src/main/java/seedu/malitio/storage/XmlAdaptedDeadline.java new file mode 100644 index 000000000000..596e98957965 --- /dev/null +++ b/src/main/java/seedu/malitio/storage/XmlAdaptedDeadline.java @@ -0,0 +1,61 @@ +package seedu.malitio.storage; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; + +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.DateTime; +import seedu.malitio.model.task.Deadline; +import seedu.malitio.model.task.Name; +import seedu.malitio.model.task.ReadOnlyDeadline; + +public class XmlAdaptedDeadline { + + @XmlElement(required = true) + private String name; + + + @XmlElement(required = true) + private String due; + private List tagged = new ArrayList<>(); + + /** + * No-arg constructor for JAXB use. + */ + public XmlAdaptedDeadline() {} + + + /** + * Converts a given Schedule into this class for JAXB use. + * + * @param source future changes to this will not affect the created XmlAdaptedTask + */ + public XmlAdaptedDeadline(ReadOnlyDeadline source) { + name = source.getName().fullName; + due = source.getDue().toString(); + tagged = new ArrayList<>(); + for (Tag tag : source.getTags()) { + tagged.add(new XmlAdaptedTag(tag)); + } + } + + /** + * Converts this jaxb-friendly adapted task object into the model's Task object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted Task + */ + public Deadline toModelType() throws IllegalValueException { + final List taskTags = new ArrayList<>(); + for (XmlAdaptedTag tag : tagged) { + taskTags.add(tag.toModelType()); + } + final Name name = new Name(this.name); + final DateTime due = new DateTime(this.due); + final UniqueTagList tags = new UniqueTagList(taskTags); + return new Deadline(name, due, tags); + } +} diff --git a/src/main/java/seedu/malitio/storage/XmlAdaptedEvent.java b/src/main/java/seedu/malitio/storage/XmlAdaptedEvent.java new file mode 100644 index 000000000000..9cd4ab930bbe --- /dev/null +++ b/src/main/java/seedu/malitio/storage/XmlAdaptedEvent.java @@ -0,0 +1,67 @@ +package seedu.malitio.storage; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; + +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.DateTime; +import seedu.malitio.model.task.Event; +import seedu.malitio.model.task.Name; +import seedu.malitio.model.task.ReadOnlyEvent; + +public class XmlAdaptedEvent { + + @XmlElement(required = true) + private String name; + + + @XmlElement(required = true) + private String start; + + @XmlElement(required = true) + private String end; + + private List tagged = new ArrayList<>(); + + /** + * No-arg constructor for JAXB use. + */ + public XmlAdaptedEvent() {} + + + /** + * Converts a given Schedule into this class for JAXB use. + * + * @param source future changes to this will not affect the created XmlAdaptedTask + */ + public XmlAdaptedEvent(ReadOnlyEvent source) { + name = source.getName().fullName; + start = source.getStart().toString(); + end = source.getEnd().toString(); + tagged = new ArrayList<>(); + for (Tag tag : source.getTags()) { + tagged.add(new XmlAdaptedTag(tag)); + } + } + + /** + * Converts this jaxb-friendly adapted task object into the model's Task object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted Task + */ + public Event toModelType() throws IllegalValueException { + final List taskTags = new ArrayList<>(); + for (XmlAdaptedTag tag : tagged) { + taskTags.add(tag.toModelType()); + } + final Name name = new Name(this.name); + final DateTime start = new DateTime(this.start); + final DateTime end = new DateTime(this.end); + final UniqueTagList tags = new UniqueTagList(taskTags); + return new Event(name, start, end, tags); + } +} diff --git a/src/main/java/seedu/malitio/storage/XmlAdaptedFloatingTask.java b/src/main/java/seedu/malitio/storage/XmlAdaptedFloatingTask.java new file mode 100644 index 000000000000..90dea84c4ea0 --- /dev/null +++ b/src/main/java/seedu/malitio/storage/XmlAdaptedFloatingTask.java @@ -0,0 +1,57 @@ +package seedu.malitio.storage; + +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.*; + +import javax.xml.bind.annotation.XmlElement; +import java.util.ArrayList; +import java.util.List; + +/** + * JAXB-friendly version of the Task. + */ +public class XmlAdaptedFloatingTask { + + @XmlElement(required = true) + private String name; + + + @XmlElement + private List tagged = new ArrayList<>(); + + /** + * No-arg constructor for JAXB use. + */ + public XmlAdaptedFloatingTask() {} + + + /** + * Converts a given Task into this class for JAXB use. + * + * @param source future changes to this will not affect the created XmlAdaptedTask + */ + public XmlAdaptedFloatingTask(ReadOnlyFloatingTask source) { + name = source.getName().fullName; + tagged = new ArrayList<>(); + for (Tag tag : source.getTags()) { + tagged.add(new XmlAdaptedTag(tag)); + } + } + + /** + * Converts this jaxb-friendly adapted task object into the model's Task object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted Task + */ + public FloatingTask toModelType() throws IllegalValueException { + final List taskTags = new ArrayList<>(); + for (XmlAdaptedTag tag : tagged) { + taskTags.add(tag.toModelType()); + } + final Name name = new Name(this.name); + final UniqueTagList tags = new UniqueTagList(taskTags); + return new FloatingTask(name, tags); + } +} diff --git a/src/main/java/seedu/address/storage/XmlAdaptedTag.java b/src/main/java/seedu/malitio/storage/XmlAdaptedTag.java similarity index 77% rename from src/main/java/seedu/address/storage/XmlAdaptedTag.java rename to src/main/java/seedu/malitio/storage/XmlAdaptedTag.java index b9723fafbc67..1bff4d740366 100644 --- a/src/main/java/seedu/address/storage/XmlAdaptedTag.java +++ b/src/main/java/seedu/malitio/storage/XmlAdaptedTag.java @@ -1,8 +1,8 @@ -package seedu.address.storage; +package seedu.malitio.storage; -import seedu.address.commons.util.CollectionUtil; -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.tag.Tag; +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.commons.util.CollectionUtil; +import seedu.malitio.model.tag.Tag; import javax.xml.bind.annotation.XmlValue; @@ -31,7 +31,7 @@ public XmlAdaptedTag(Tag source) { /** * Converts this jaxb-friendly adapted tag object into the model's Tag object. * - * @throws IllegalValueException if there were any data constraints violated in the adapted person + * @throws IllegalValueException if there were any data constraints violated in the adapted task */ public Tag toModelType() throws IllegalValueException { return new Tag(tagName); diff --git a/src/main/java/seedu/address/storage/XmlFileStorage.java b/src/main/java/seedu/malitio/storage/XmlFileStorage.java similarity index 57% rename from src/main/java/seedu/address/storage/XmlFileStorage.java rename to src/main/java/seedu/malitio/storage/XmlFileStorage.java index 27a5210cadaf..d116d276872a 100644 --- a/src/main/java/seedu/address/storage/XmlFileStorage.java +++ b/src/main/java/seedu/malitio/storage/XmlFileStorage.java @@ -1,35 +1,35 @@ -package seedu.address.storage; +package seedu.malitio.storage; -import seedu.address.commons.util.XmlUtil; -import seedu.address.commons.exceptions.DataConversionException; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.commons.util.XmlUtil; import javax.xml.bind.JAXBException; import java.io.File; import java.io.FileNotFoundException; /** - * Stores addressbook data in an XML file + * Stores Malitio data in an XML file */ public class XmlFileStorage { /** - * Saves the given addressbook data to the specified file. + * Saves the given Malitio data to the specified file. */ - public static void saveDataToFile(File file, XmlSerializableAddressBook addressBook) + public static void saveDataToFile(File file, XmlSerializableMalitio malitio) throws FileNotFoundException { try { - XmlUtil.saveDataToFile(file, addressBook); + XmlUtil.saveDataToFile(file, malitio); } catch (JAXBException e) { assert false : "Unexpected exception " + e.getMessage(); } } /** - * Returns address book in the file or an empty address book + * Returns malitio in the file or an empty malitio */ - public static XmlSerializableAddressBook loadDataFromSaveFile(File file) throws DataConversionException, + public static XmlSerializableMalitio loadDataFromSaveFile(File file) throws DataConversionException, FileNotFoundException { try { - return XmlUtil.getDataFromFile(file, XmlSerializableAddressBook.class); + return XmlUtil.getDataFromFile(file, XmlSerializableMalitio.class); } catch (JAXBException e) { throw new DataConversionException(e); } diff --git a/src/main/java/seedu/malitio/storage/XmlMalitioStorage.java b/src/main/java/seedu/malitio/storage/XmlMalitioStorage.java new file mode 100644 index 000000000000..ac46f5584f2d --- /dev/null +++ b/src/main/java/seedu/malitio/storage/XmlMalitioStorage.java @@ -0,0 +1,73 @@ +package seedu.malitio.storage; + +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.commons.util.FileUtil; +import seedu.malitio.model.ReadOnlyMalitio; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Optional; +import java.util.logging.Logger; + +/** + * A class to access Malitio data stored as an xml file on the hard disk. + */ +public class XmlMalitioStorage implements MalitioStorage { + + private static final Logger logger = LogsCenter.getLogger(XmlMalitioStorage.class); + + private String filePath; + + public XmlMalitioStorage(String filePath){ + this.filePath = filePath; + } + + public String getMalitioFilePath(){ + return filePath; + } + + /** + * Similar to {@link #readMalitio()} + * @param filePath location of the data. Cannot be null + * @throws DataConversionException if the file is not in the correct format. + */ + public Optional readMalitio(String filePath) throws DataConversionException, FileNotFoundException { + assert filePath != null; + + File malitioFile = new File(filePath); + + if (!malitioFile.exists()) { + logger.info("malitio file " + malitioFile + " not found"); + return Optional.empty(); + } + + ReadOnlyMalitio malitioOptional = XmlFileStorage.loadDataFromSaveFile(new File(filePath)); + + return Optional.of(malitioOptional); + } + + /** + * Similar to {@link #savemalitio(ReadOnlyMalitio)} + * @param filePath location of the data. Cannot be null + */ + public void savemalitio(ReadOnlyMalitio malitio, String filePath) throws IOException { + assert malitio != null; + assert filePath != null; + + File file = new File(filePath); + FileUtil.createIfMissing(file); + XmlFileStorage.saveDataToFile(file, new XmlSerializableMalitio(malitio)); + } + + @Override + public Optional readMalitio() throws DataConversionException, IOException { + return readMalitio(filePath); + } + + @Override + public void savemalitio(ReadOnlyMalitio malitio) throws IOException { + savemalitio(malitio, filePath); + } +} diff --git a/src/main/java/seedu/malitio/storage/XmlSerializableMalitio.java b/src/main/java/seedu/malitio/storage/XmlSerializableMalitio.java new file mode 100644 index 000000000000..14b732b31821 --- /dev/null +++ b/src/main/java/seedu/malitio/storage/XmlSerializableMalitio.java @@ -0,0 +1,153 @@ +package seedu.malitio.storage; + +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.ReadOnlyMalitio; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.ReadOnlyDeadline; +import seedu.malitio.model.task.ReadOnlyEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.model.task.UniqueDeadlineList; +import seedu.malitio.model.task.UniqueEventList; +import seedu.malitio.model.task.UniqueFloatingTaskList; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * An Immutable Malitio that is serializable to XML format + */ +@XmlRootElement(name = "malitio") +public class XmlSerializableMalitio implements ReadOnlyMalitio { + + @XmlElement + private List floatingTasks; + @XmlElement + private List deadlines; + @XmlElement + private List events; + @XmlElement + private List tags; + + { + floatingTasks = new ArrayList<>(); + deadlines = new ArrayList<>(); + events = new ArrayList<>(); + tags = new ArrayList<>(); + } + + /** + * Empty constructor required for marshalling + */ + public XmlSerializableMalitio() {} + + /** + * Conversion + */ + public XmlSerializableMalitio(ReadOnlyMalitio src) { + floatingTasks.addAll(src.getFloatingTaskList().stream().map(XmlAdaptedFloatingTask::new).collect(Collectors.toList())); + deadlines.addAll(src.getDeadlineList().stream().map(XmlAdaptedDeadline::new).collect(Collectors.toList())); + events.addAll(src.getEventList().stream().map(XmlAdaptedEvent::new).collect(Collectors.toList())); + tags = src.getTagList(); + } + + @Override + public UniqueTagList getUniqueTagList() { + try { + return new UniqueTagList(tags); + } catch (UniqueTagList.DuplicateTagException e) { + //TODO: better error handling + e.printStackTrace(); + return null; + } + } + + @Override + public UniqueFloatingTaskList getUniqueFloatingTaskList() { + UniqueFloatingTaskList lists = new UniqueFloatingTaskList(); + for (XmlAdaptedFloatingTask p : floatingTasks) { + try { + lists.add(p.toModelType()); + } catch (IllegalValueException e) { + //TODO: better error handling + } + } + return lists; + } + + @Override + public UniqueDeadlineList getUniqueDeadlineList() { + UniqueDeadlineList lists = new UniqueDeadlineList(); + for (XmlAdaptedDeadline p : deadlines) { + try { + lists.add(p.toModelType()); + } catch (IllegalValueException e) { + //TODO: better error handling + } + } + return lists; + } + + @Override + public UniqueEventList getUniqueEventList() { + UniqueEventList lists = new UniqueEventList(); + for (XmlAdaptedEvent p : events) { + try { + lists.add(p.toModelType()); + } catch (IllegalValueException e) { + //TODO: better error handling + } + } + return lists; + } + + @Override + public List getFloatingTaskList() { + return floatingTasks.stream().map(p -> { + try { + return p.toModelType(); + } catch (IllegalValueException e) { + e.printStackTrace(); + //TODO: better error handling + return null; + } + }).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public List getDeadlineList() { + return deadlines.stream().map(p -> { + try { + return p.toModelType(); + } catch (IllegalValueException e) { + e.printStackTrace(); + //TODO: better error handling + return null; + } + }).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public List getEventList() { + return events.stream().map(p -> { + try { + return p.toModelType(); + } catch (IllegalValueException e) { + e.printStackTrace(); + //TODO: better error handling + return null; + } + }).collect(Collectors.toCollection(ArrayList::new)); + } + + @Override + public List getTagList() { + return Collections.unmodifiableList(tags); + } + + +} diff --git a/src/main/java/seedu/address/ui/CommandBox.java b/src/main/java/seedu/malitio/ui/CommandBox.java similarity index 93% rename from src/main/java/seedu/address/ui/CommandBox.java rename to src/main/java/seedu/malitio/ui/CommandBox.java index 2e1409a3016c..ee7b1d3d8145 100644 --- a/src/main/java/seedu/address/ui/CommandBox.java +++ b/src/main/java/seedu/malitio/ui/CommandBox.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.malitio.ui; import com.google.common.eventbus.Subscribe; import javafx.fxml.FXML; @@ -7,11 +7,11 @@ import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; -import seedu.address.commons.events.ui.IncorrectCommandAttemptedEvent; -import seedu.address.logic.Logic; -import seedu.address.logic.commands.*; -import seedu.address.commons.util.FxViewUtil; -import seedu.address.commons.core.LogsCenter; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.events.ui.IncorrectCommandAttemptedEvent; +import seedu.malitio.commons.util.FxViewUtil; +import seedu.malitio.logic.Logic; +import seedu.malitio.logic.commands.*; import java.util.logging.Logger; diff --git a/src/main/java/seedu/malitio/ui/DeadlineCard.java b/src/main/java/seedu/malitio/ui/DeadlineCard.java new file mode 100644 index 000000000000..5c9742f04231 --- /dev/null +++ b/src/main/java/seedu/malitio/ui/DeadlineCard.java @@ -0,0 +1,60 @@ +package seedu.malitio.ui; + +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import seedu.malitio.model.task.ReadOnlyDeadline; + +public class DeadlineCard extends UiPart{ + + private static final String FXML = "DeadlineListCard.fxml"; + + @FXML + private HBox cardPane2; + @FXML + private Label name; + @FXML + private Label id; + @FXML + private Label due; + + @FXML + private Label tags; + + private ReadOnlyDeadline deadline; + private int displayedIndex; + + public DeadlineCard(){ + + } + + public static DeadlineCard load(ReadOnlyDeadline deadline, int displayedIndex){ + DeadlineCard card = new DeadlineCard(); + card.deadline = deadline; + card.displayedIndex = displayedIndex; + return UiPartLoader.loadUiPart(card); + } + + @FXML + public void initialize() { + name.setText(deadline.getName().fullName); + id.setText(displayedIndex + ". "); + due.setText("Due: "+ deadline.getDue().toString()); + tags.setText(deadline.tagsString()); + } + + public HBox getLayout() { + return cardPane2; + } + + @Override + public void setNode(Node node) { + cardPane2 = (HBox)node; + } + + @Override + public String getFxmlPath() { + return FXML; + } +} diff --git a/src/main/java/seedu/malitio/ui/DeadlineListPanel.java b/src/main/java/seedu/malitio/ui/DeadlineListPanel.java new file mode 100644 index 000000000000..724ad76afcd3 --- /dev/null +++ b/src/main/java/seedu/malitio/ui/DeadlineListPanel.java @@ -0,0 +1,107 @@ +package seedu.malitio.ui; + +import javafx.application.Platform; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.SplitPane; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.events.ui.TaskPanelSelectionChangedEvent; +import seedu.malitio.model.task.ReadOnlyDeadline; +import java.util.logging.Logger; + +/** + * Panel containing the list of deadlines. + */ +public class DeadlineListPanel extends UiPart { + private final Logger logger = LogsCenter.getLogger(DeadlineListPanel.class); + private static final String FXML = "DeadlineListPanel.fxml"; + private VBox panel; + private AnchorPane placeHolderPane; + + @FXML + private ListView deadlineListView; + + public DeadlineListPanel() { + super(); + } + + @Override + public void setNode(Node node) { + panel = (VBox) node; + } + + @Override + public String getFxmlPath() { + return FXML; + } + + @Override + public void setPlaceholder(AnchorPane pane) { + this.placeHolderPane = pane; + } + + public static DeadlineListPanel load(Stage primaryStage, AnchorPane deadlineListPanelPlaceholder, + ObservableList deadlineList) { + DeadlineListPanel deadlineListPanel = + UiPartLoader.loadUiPart(primaryStage, deadlineListPanelPlaceholder, new DeadlineListPanel()); + deadlineListPanel.configure(deadlineList); + return deadlineListPanel; + } + + private void configure(ObservableList deadlineList) { + setConnections(deadlineList); + addToPlaceholder(); + } + + private void setConnections(ObservableList deadlineList) { + deadlineListView.setItems(deadlineList); + deadlineListView.setCellFactory(listView -> new DeadlineListViewCell()); + setEventHandlerForSelectionChangeEvent(); + } + + private void addToPlaceholder() { + SplitPane.setResizableWithParent(placeHolderPane, false); + placeHolderPane.getChildren().add(panel); + } + + private void setEventHandlerForSelectionChangeEvent() { + deadlineListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if (newValue != null) { + logger.fine("Selection in task list panel changed to : '" + newValue + "'"); + raise(new TaskPanelSelectionChangedEvent(newValue)); + } + }); + } + + public void scrollTo(int index) { + Platform.runLater(() -> { + deadlineListView.scrollTo(index); + deadlineListView.getSelectionModel().clearAndSelect(index); + }); + } + + class DeadlineListViewCell extends ListCell { + + public DeadlineListViewCell() { + } + + @Override + protected void updateItem(ReadOnlyDeadline deadline, boolean empty) { + super.updateItem(deadline, empty); + + if (empty || deadline == null) { + setGraphic(null); + setText(null); + } else { + setGraphic(DeadlineCard.load(deadline, getIndex() + 1).getLayout()); + } + } + } + +} diff --git a/src/main/java/seedu/malitio/ui/EventCard.java b/src/main/java/seedu/malitio/ui/EventCard.java new file mode 100644 index 000000000000..7cbb2652bf8b --- /dev/null +++ b/src/main/java/seedu/malitio/ui/EventCard.java @@ -0,0 +1,62 @@ +package seedu.malitio.ui; + +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import seedu.malitio.model.task.ReadOnlyEvent; + +public class EventCard extends UiPart{ + + private static final String FXML = "EventListCard.fxml"; + + @FXML + private HBox cardPane3; + @FXML + private Label name; + @FXML + private Label id; + @FXML + private Label start; + @FXML + private Label end; + @FXML + private Label tags; + + private ReadOnlyEvent event; + private int displayedIndex; + + public EventCard(){ + + } + + public static EventCard load(ReadOnlyEvent event, int displayedIndex){ + EventCard card = new EventCard(); + card.event = event; + card.displayedIndex = displayedIndex; + return UiPartLoader.loadUiPart(card); + } + + @FXML + public void initialize() { + name.setText(event.getName().fullName); + id.setText(displayedIndex + ". "); + start.setText("Start: "+ event.getStart().toString()); + end.setText("End: " + event.getEnd().toString()); + tags.setText(event.tagsString()); + } + + public HBox getLayout() { + return cardPane3; + } + + @Override + public void setNode(Node node) { + cardPane3 = (HBox)node; + } + + @Override + public String getFxmlPath() { + return FXML; + } +} diff --git a/src/main/java/seedu/malitio/ui/EventListPanel.java b/src/main/java/seedu/malitio/ui/EventListPanel.java new file mode 100644 index 000000000000..6195769681fc --- /dev/null +++ b/src/main/java/seedu/malitio/ui/EventListPanel.java @@ -0,0 +1,108 @@ +package seedu.malitio.ui; + +import javafx.application.Platform; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.SplitPane; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.events.ui.TaskPanelSelectionChangedEvent; +import seedu.malitio.model.task.ReadOnlyEvent; + +import java.util.logging.Logger; + +/** + * Panel containing the list of deadlines. + */ +public class EventListPanel extends UiPart { + private final Logger logger = LogsCenter.getLogger(EventListPanel.class); + private static final String FXML = "EventListPanel.fxml"; + private VBox panel; + private AnchorPane placeHolderPane; + + @FXML + private ListView eventListView; + + public EventListPanel() { + super(); + } + + @Override + public void setNode(Node node) { + panel = (VBox) node; + } + + @Override + public String getFxmlPath() { + return FXML; + } + + @Override + public void setPlaceholder(AnchorPane pane) { + this.placeHolderPane = pane; + } + + public static EventListPanel load(Stage primaryStage, AnchorPane eventListPanelPlaceholder, + ObservableList eventList) { + EventListPanel eventListPanel = + UiPartLoader.loadUiPart(primaryStage, eventListPanelPlaceholder, new EventListPanel()); + eventListPanel.configure(eventList); + return eventListPanel; + } + + private void configure(ObservableList eventList) { + setConnections(eventList); + addToPlaceholder(); + } + + private void setConnections(ObservableList eventList) { + eventListView.setItems(eventList); + eventListView.setCellFactory(listView -> new EventListViewCell()); + setEventHandlerForSelectionChangeEvent(); + } + + private void addToPlaceholder() { + SplitPane.setResizableWithParent(placeHolderPane, false); + placeHolderPane.getChildren().add(panel); + } + + private void setEventHandlerForSelectionChangeEvent() { + eventListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if (newValue != null) { + logger.fine("Selection in task list panel changed to : '" + newValue + "'"); + raise(new TaskPanelSelectionChangedEvent(newValue)); + } + }); + } + + public void scrollTo(int index) { + Platform.runLater(() -> { + eventListView.scrollTo(index); + eventListView.getSelectionModel().clearAndSelect(index); + }); + } + + class EventListViewCell extends ListCell { + + public EventListViewCell() { + } + + @Override + protected void updateItem(ReadOnlyEvent event, boolean empty) { + super.updateItem(event, empty); + + if (empty || event == null) { + setGraphic(null); + setText(null); + } else { + setGraphic(EventCard.load(event, getIndex() + 1).getLayout()); + } + } + } + +} diff --git a/src/main/java/seedu/malitio/ui/FloatingTaskCard.java b/src/main/java/seedu/malitio/ui/FloatingTaskCard.java new file mode 100644 index 000000000000..8f8c99d0ceaa --- /dev/null +++ b/src/main/java/seedu/malitio/ui/FloatingTaskCard.java @@ -0,0 +1,56 @@ +package seedu.malitio.ui; + +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import seedu.malitio.model.task.ReadOnlyFloatingTask; + +public class FloatingTaskCard extends UiPart{ + + private static final String FXML = "TaskListCard.fxml"; + + @FXML + private HBox cardPane; + @FXML + private Label name; + @FXML + private Label id; + @FXML + private Label tags; + + private ReadOnlyFloatingTask task; + private int displayedIndex; + + public FloatingTaskCard(){ + + } + + public static FloatingTaskCard load(ReadOnlyFloatingTask task, int displayedIndex){ + FloatingTaskCard card = new FloatingTaskCard(); + card.task = task; + card.displayedIndex = displayedIndex; + return UiPartLoader.loadUiPart(card); + } + + @FXML + public void initialize() { + name.setText(task.getName().fullName); + id.setText(displayedIndex + ". "); + tags.setText(task.tagsString()); + } + + public HBox getLayout() { + return cardPane; + } + + @Override + public void setNode(Node node) { + cardPane = (HBox)node; + } + + @Override + public String getFxmlPath() { + return FXML; + } +} diff --git a/src/main/java/seedu/malitio/ui/FloatingTaskListPanel.java b/src/main/java/seedu/malitio/ui/FloatingTaskListPanel.java new file mode 100644 index 000000000000..1ea868dd8d75 --- /dev/null +++ b/src/main/java/seedu/malitio/ui/FloatingTaskListPanel.java @@ -0,0 +1,108 @@ +package seedu.malitio.ui; + +import javafx.application.Platform; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.SplitPane; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.events.ui.TaskPanelSelectionChangedEvent; +import seedu.malitio.model.task.ReadOnlyFloatingTask; + +import java.util.logging.Logger; + +/** + * Panel containing the list of tasks. + */ +public class FloatingTaskListPanel extends UiPart { + private final Logger logger = LogsCenter.getLogger(FloatingTaskListPanel.class); + private static final String FXML = "TaskListPanel.fxml"; + private VBox panel; + private AnchorPane placeHolderPane; + + @FXML + private ListView taskListView; + + public FloatingTaskListPanel() { + super(); + } + + @Override + public void setNode(Node node) { + panel = (VBox) node; + } + + @Override + public String getFxmlPath() { + return FXML; + } + + @Override + public void setPlaceholder(AnchorPane pane) { + this.placeHolderPane = pane; + } + + public static FloatingTaskListPanel load(Stage primaryStage, AnchorPane taskListPanelPlaceholder, + ObservableList taskList) { + FloatingTaskListPanel taskListPanel = + UiPartLoader.loadUiPart(primaryStage, taskListPanelPlaceholder, new FloatingTaskListPanel()); + taskListPanel.configure(taskList); + return taskListPanel; + } + + private void configure(ObservableList taskList) { + setConnections(taskList); + addToPlaceholder(); + } + + private void setConnections(ObservableList taskList) { + taskListView.setItems(taskList); + taskListView.setCellFactory(listView -> new TaskListViewCell()); + setEventHandlerForSelectionChangeEvent(); + } + + private void addToPlaceholder() { + SplitPane.setResizableWithParent(placeHolderPane, false); + placeHolderPane.getChildren().add(panel); + } + + private void setEventHandlerForSelectionChangeEvent() { + taskListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if (newValue != null) { + logger.fine("Selection in task list panel changed to : '" + newValue + "'"); + raise(new TaskPanelSelectionChangedEvent(newValue)); + } + }); + } + + public void scrollTo(int index) { + Platform.runLater(() -> { + taskListView.scrollTo(index); + taskListView.getSelectionModel().clearAndSelect(index); + }); + } + + class TaskListViewCell extends ListCell { + + public TaskListViewCell() { + } + + @Override + protected void updateItem(ReadOnlyFloatingTask task, boolean empty) { + super.updateItem(task, empty); + + if (empty || task == null) { + setGraphic(null); + setText(null); + } else { + setGraphic(FloatingTaskCard.load(task, getIndex() + 1).getLayout()); + } + } + } + +} diff --git a/src/main/java/seedu/address/ui/HelpWindow.java b/src/main/java/seedu/malitio/ui/HelpWindow.java similarity index 90% rename from src/main/java/seedu/address/ui/HelpWindow.java rename to src/main/java/seedu/malitio/ui/HelpWindow.java index 45b765ab6a0c..6630ed8bae17 100644 --- a/src/main/java/seedu/address/ui/HelpWindow.java +++ b/src/main/java/seedu/malitio/ui/HelpWindow.java @@ -1,12 +1,12 @@ -package seedu.address.ui; +package seedu.malitio.ui; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.layout.AnchorPane; import javafx.scene.web.WebView; import javafx.stage.Stage; -import seedu.address.commons.util.FxViewUtil; -import seedu.address.commons.core.LogsCenter; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.util.FxViewUtil; import java.util.logging.Logger; @@ -20,7 +20,7 @@ public class HelpWindow extends UiPart { private static final String FXML = "HelpWindow.fxml"; private static final String TITLE = "Help"; private static final String USERGUIDE_URL = - "https://github.com/se-edu/addressbook-level4/blob/master/docs/UserGuide.md"; + "https://github.com/CS2103AUG2016-T13-C3/main/blob/master/docs/UserGuide.md"; private AnchorPane mainPane; diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/malitio/ui/MainWindow.java similarity index 69% rename from src/main/java/seedu/address/ui/MainWindow.java rename to src/main/java/seedu/malitio/ui/MainWindow.java index 2c76aced3b04..296af46b2421 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/malitio/ui/MainWindow.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.malitio.ui; import javafx.fxml.FXML; import javafx.scene.Node; @@ -8,12 +8,12 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; -import seedu.address.commons.core.Config; -import seedu.address.commons.core.GuiSettings; -import seedu.address.commons.events.ui.ExitAppRequestEvent; -import seedu.address.logic.Logic; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.ReadOnlyPerson; +import seedu.malitio.commons.core.Config; +import seedu.malitio.commons.core.GuiSettings; +import seedu.malitio.commons.events.ui.ExitAppRequestEvent; +import seedu.malitio.logic.Logic; +import seedu.malitio.model.UserPrefs; +import seedu.malitio.model.task.ReadOnlyFloatingTask; /** * The Main Window. Provides the basic application layout containing @@ -21,7 +21,7 @@ */ public class MainWindow extends UiPart { - private static final String ICON = "/images/address_book_32.png"; + private static final String ICON = "/images/malitio.png"; private static final String FXML = "MainWindow.fxml"; public static final int MIN_HEIGHT = 600; public static final int MIN_WIDTH = 450; @@ -29,8 +29,9 @@ public class MainWindow extends UiPart { private Logic logic; // Independent Ui parts residing in this Ui container - private BrowserPanel browserPanel; - private PersonListPanel personListPanel; + private FloatingTaskListPanel taskListPanel; + private DeadlineListPanel deadlineListPanel; + private EventListPanel eventListPanel; private ResultDisplay resultDisplay; private StatusBarFooter statusBarFooter; private CommandBox commandBox; @@ -41,10 +42,7 @@ public class MainWindow extends UiPart { private VBox rootLayout; private Scene scene; - private String addressBookName; - - @FXML - private AnchorPane browserPlaceholder; + private String malitioName; @FXML private AnchorPane commandBoxPlaceholder; @@ -53,7 +51,13 @@ public class MainWindow extends UiPart { private MenuItem helpMenuItem; @FXML - private AnchorPane personListPanelPlaceholder; + private AnchorPane taskListPanelPlaceholder; + + @FXML + private AnchorPane deadlineListPanelPlaceholder; + + @FXML + private AnchorPane eventListPanelPlaceholder; @FXML private AnchorPane resultDisplayPlaceholder; @@ -79,16 +83,16 @@ public String getFxmlPath() { public static MainWindow load(Stage primaryStage, Config config, UserPrefs prefs, Logic logic) { MainWindow mainWindow = UiPartLoader.loadUiPart(primaryStage, new MainWindow()); - mainWindow.configure(config.getAppTitle(), config.getAddressBookName(), config, prefs, logic); + mainWindow.configure(config.getAppTitle(), config.getMalitioName(), config, prefs, logic); return mainWindow; } - private void configure(String appTitle, String addressBookName, Config config, UserPrefs prefs, + private void configure(String appTitle, String malitioName, Config config, UserPrefs prefs, Logic logic) { //Set dependencies this.logic = logic; - this.addressBookName = addressBookName; + this.malitioName = malitioName; this.config = config; this.userPrefs = prefs; @@ -108,10 +112,11 @@ private void setAccelerators() { } void fillInnerParts() { - browserPanel = BrowserPanel.load(browserPlaceholder); - personListPanel = PersonListPanel.load(primaryStage, getPersonListPlaceholder(), logic.getFilteredPersonList()); + taskListPanel = FloatingTaskListPanel.load(primaryStage, getTaskListPanelPlaceholder(), logic.getFilteredFloatingTaskList()); + deadlineListPanel = DeadlineListPanel.load(primaryStage, getDeadlineListPanelPlaceholder(), logic.getFilteredDeadlineList()); + eventListPanel = EventListPanel.load(primaryStage, getEventListPanelPlaceholder(), logic.getFilteredEventList()); resultDisplay = ResultDisplay.load(primaryStage, getResultDisplayPlaceholder()); - statusBarFooter = StatusBarFooter.load(primaryStage, getStatusbarPlaceholder(), config.getAddressBookFilePath()); + statusBarFooter = StatusBarFooter.load(primaryStage, getStatusbarPlaceholder(), config.getMalitioFilePath()); commandBox = CommandBox.load(primaryStage, getCommandBoxPlaceholder(), resultDisplay, logic); } @@ -127,8 +132,16 @@ private AnchorPane getResultDisplayPlaceholder() { return resultDisplayPlaceholder; } - public AnchorPane getPersonListPlaceholder() { - return personListPanelPlaceholder; + public AnchorPane getTaskListPanelPlaceholder() { + return taskListPanelPlaceholder; + } + + public AnchorPane getDeadlineListPanelPlaceholder() { + return deadlineListPanelPlaceholder; + } + + private AnchorPane getEventListPanelPlaceholder() { + return eventListPanelPlaceholder; } public void hide() { @@ -182,15 +195,12 @@ private void handleExit() { raise(new ExitAppRequestEvent()); } - public PersonListPanel getPersonListPanel() { - return this.personListPanel; + public FloatingTaskListPanel getTaskListPanel() { + return this.taskListPanel; } - - public void loadPersonPage(ReadOnlyPerson person) { - browserPanel.loadPersonPage(person); + + public DeadlineListPanel getDeadlineListPanel() { + return this.deadlineListPanel; } - public void releaseResources() { - browserPanel.freeResources(); - } } diff --git a/src/main/java/seedu/address/ui/ResultDisplay.java b/src/main/java/seedu/malitio/ui/ResultDisplay.java similarity index 96% rename from src/main/java/seedu/address/ui/ResultDisplay.java rename to src/main/java/seedu/malitio/ui/ResultDisplay.java index 37284ee6c696..31c66737e942 100644 --- a/src/main/java/seedu/address/ui/ResultDisplay.java +++ b/src/main/java/seedu/malitio/ui/ResultDisplay.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.malitio.ui; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; @@ -6,7 +6,7 @@ import javafx.scene.control.TextArea; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; -import seedu.address.commons.util.FxViewUtil; +import seedu.malitio.commons.util.FxViewUtil; /** * A ui for the status bar that is displayed at the header of the application. diff --git a/src/main/java/seedu/address/ui/StatusBarFooter.java b/src/main/java/seedu/malitio/ui/StatusBarFooter.java similarity index 91% rename from src/main/java/seedu/address/ui/StatusBarFooter.java rename to src/main/java/seedu/malitio/ui/StatusBarFooter.java index f74f66be6fc9..f65b863d6e66 100644 --- a/src/main/java/seedu/address/ui/StatusBarFooter.java +++ b/src/main/java/seedu/malitio/ui/StatusBarFooter.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.malitio.ui; import com.google.common.eventbus.Subscribe; import javafx.fxml.FXML; @@ -7,9 +7,10 @@ import javafx.scene.layout.GridPane; import javafx.stage.Stage; import org.controlsfx.control.StatusBar; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.events.model.AddressBookChangedEvent; -import seedu.address.commons.util.FxViewUtil; + +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.events.model.MalitioChangedEvent; +import seedu.malitio.commons.util.FxViewUtil; import java.util.Date; import java.util.logging.Logger; @@ -90,7 +91,7 @@ public String getFxmlPath() { } @Subscribe - public void handleAddressBookChangedEvent(AddressBookChangedEvent abce) { + public void handlemalitioChangedEvent(MalitioChangedEvent abce) { String lastUpdated = (new Date()).toString(); logger.info(LogsCenter.getEventHandlingLogMessage(abce, "Setting last updated status to " + lastUpdated)); setSyncStatus("Last Updated: " + lastUpdated); diff --git a/src/main/java/seedu/address/ui/Ui.java b/src/main/java/seedu/malitio/ui/Ui.java similarity index 88% rename from src/main/java/seedu/address/ui/Ui.java rename to src/main/java/seedu/malitio/ui/Ui.java index e6a67fe8c027..0f4284c07f6d 100644 --- a/src/main/java/seedu/address/ui/Ui.java +++ b/src/main/java/seedu/malitio/ui/Ui.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.malitio.ui; import javafx.stage.Stage; diff --git a/src/main/java/seedu/address/ui/UiManager.java b/src/main/java/seedu/malitio/ui/UiManager.java similarity index 80% rename from src/main/java/seedu/address/ui/UiManager.java rename to src/main/java/seedu/malitio/ui/UiManager.java index 4a4dba3a2f6e..7a22428b3f32 100644 --- a/src/main/java/seedu/address/ui/UiManager.java +++ b/src/main/java/seedu/malitio/ui/UiManager.java @@ -1,4 +1,4 @@ -package seedu.address.ui; +package seedu.malitio.ui; import com.google.common.eventbus.Subscribe; import javafx.application.Platform; @@ -6,17 +6,17 @@ import javafx.scene.control.Alert.AlertType; import javafx.scene.image.Image; import javafx.stage.Stage; -import seedu.address.MainApp; -import seedu.address.commons.core.ComponentManager; -import seedu.address.commons.core.Config; -import seedu.address.commons.core.LogsCenter; -import seedu.address.commons.events.storage.DataSavingExceptionEvent; -import seedu.address.commons.events.ui.JumpToListRequestEvent; -import seedu.address.commons.events.ui.PersonPanelSelectionChangedEvent; -import seedu.address.commons.events.ui.ShowHelpRequestEvent; -import seedu.address.commons.util.StringUtil; -import seedu.address.logic.Logic; -import seedu.address.model.UserPrefs; +import seedu.malitio.MainApp; +import seedu.malitio.commons.core.ComponentManager; +import seedu.malitio.commons.core.Config; +import seedu.malitio.commons.core.LogsCenter; +import seedu.malitio.commons.events.storage.DataSavingExceptionEvent; +import seedu.malitio.commons.events.ui.JumpToListRequestEvent; +import seedu.malitio.commons.events.ui.TaskPanelSelectionChangedEvent; +import seedu.malitio.commons.events.ui.ShowHelpRequestEvent; +import seedu.malitio.commons.util.StringUtil; +import seedu.malitio.logic.Logic; +import seedu.malitio.model.UserPrefs; import java.util.logging.Logger; @@ -25,7 +25,7 @@ */ public class UiManager extends ComponentManager implements Ui { private static final Logger logger = LogsCenter.getLogger(UiManager.class); - private static final String ICON_APPLICATION = "/images/address_book_32.png"; + private static final String ICON_APPLICATION = "/images/malitio.png"; private Logic logic; private Config config; @@ -62,7 +62,6 @@ public void start(Stage primaryStage) { public void stop() { prefs.updateLastUsedGuiSetting(mainWindow.getCurrentGuiSetting()); mainWindow.hide(); - mainWindow.releaseResources(); } private void showFileOperationAlertAndWait(String description, String details, Throwable cause) { @@ -114,13 +113,12 @@ private void handleShowHelpEvent(ShowHelpRequestEvent event) { @Subscribe private void handleJumpToListRequestEvent(JumpToListRequestEvent event) { logger.info(LogsCenter.getEventHandlingLogMessage(event)); - mainWindow.getPersonListPanel().scrollTo(event.targetIndex); + mainWindow.getTaskListPanel().scrollTo(event.targetIndex); } @Subscribe - private void handlePersonPanelSelectionChangedEvent(PersonPanelSelectionChangedEvent event){ + private void handleTaskPanelSelectionChangedEvent(TaskPanelSelectionChangedEvent event){ logger.info(LogsCenter.getEventHandlingLogMessage(event)); - mainWindow.loadPersonPage(event.getNewSelection()); } } diff --git a/src/main/java/seedu/address/ui/UiPart.java b/src/main/java/seedu/malitio/ui/UiPart.java similarity index 94% rename from src/main/java/seedu/address/ui/UiPart.java rename to src/main/java/seedu/malitio/ui/UiPart.java index 0a4ceb33e9b7..2dd7f1102a0f 100644 --- a/src/main/java/seedu/address/ui/UiPart.java +++ b/src/main/java/seedu/malitio/ui/UiPart.java @@ -1,13 +1,13 @@ -package seedu.address.ui; +package seedu.malitio.ui; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.layout.AnchorPane; import javafx.stage.Modality; import javafx.stage.Stage; -import seedu.address.commons.core.EventsCenter; -import seedu.address.commons.events.BaseEvent; -import seedu.address.commons.util.AppUtil; +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.commons.events.BaseEvent; +import seedu.malitio.commons.util.AppUtil; /** * Base class for UI parts. diff --git a/src/main/java/seedu/address/ui/UiPartLoader.java b/src/main/java/seedu/malitio/ui/UiPartLoader.java similarity index 97% rename from src/main/java/seedu/address/ui/UiPartLoader.java rename to src/main/java/seedu/malitio/ui/UiPartLoader.java index f880685a5b15..d3593644313e 100644 --- a/src/main/java/seedu/address/ui/UiPartLoader.java +++ b/src/main/java/seedu/malitio/ui/UiPartLoader.java @@ -1,10 +1,10 @@ -package seedu.address.ui; +package seedu.malitio.ui; import javafx.fxml.FXMLLoader; import javafx.scene.Node; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; -import seedu.address.MainApp; +import seedu.malitio.MainApp; /** * A utility class to load UiParts from FXML files. diff --git a/src/main/resources/images/malitio.png b/src/main/resources/images/malitio.png new file mode 100644 index 000000000000..b9024b5a51c1 Binary files /dev/null and b/src/main/resources/images/malitio.png differ diff --git a/src/main/resources/view/CommandBox.fxml b/src/main/resources/view/CommandBox.fxml index 575de420b994..20dccb243883 100644 --- a/src/main/resources/view/CommandBox.fxml +++ b/src/main/resources/view/CommandBox.fxml @@ -2,8 +2,10 @@ - - + + diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css index 8043b344253a..0d3593de87f1 100644 --- a/src/main/resources/view/DarkTheme.css +++ b/src/main/resources/view/DarkTheme.css @@ -283,6 +283,6 @@ -fx-text-fill: #F70D1A; } -#filterField, #personListPanel, #personWebpage { +#filterField, #taskListPanel, #taskWebpage { -fx-effect: innershadow(gaussian, black, 10, 0, 0, 0); } \ No newline at end of file diff --git a/src/main/resources/view/DeadlineListCard.fxml b/src/main/resources/view/DeadlineListCard.fxml new file mode 100644 index 000000000000..c179dcf9e9da --- /dev/null +++ b/src/main/resources/view/DeadlineListCard.fxml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/DeadlineListPanel.fxml b/src/main/resources/view/DeadlineListPanel.fxml new file mode 100644 index 000000000000..899759ea7088 --- /dev/null +++ b/src/main/resources/view/DeadlineListPanel.fxml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/view/DefaultBrowserPlaceHolderScreen.fxml b/src/main/resources/view/DefaultBrowserPlaceHolderScreen.fxml deleted file mode 100644 index bc761118235a..000000000000 --- a/src/main/resources/view/DefaultBrowserPlaceHolderScreen.fxml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - diff --git a/src/main/resources/view/EventListCard.fxml b/src/main/resources/view/EventListCard.fxml new file mode 100644 index 000000000000..dd5bae1ac816 --- /dev/null +++ b/src/main/resources/view/EventListCard.fxml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/EventListPanel.fxml b/src/main/resources/view/EventListPanel.fxml new file mode 100644 index 000000000000..d655780ac5e6 --- /dev/null +++ b/src/main/resources/view/EventListPanel.fxml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/view/HelpWindow.fxml b/src/main/resources/view/HelpWindow.fxml index c4cbd84cac28..2e894f30aa07 100644 --- a/src/main/resources/view/HelpWindow.fxml +++ b/src/main/resources/view/HelpWindow.fxml @@ -1,8 +1,11 @@ - - + + - + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index 2f9235c621d8..7716002c96a8 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -1,56 +1,75 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml deleted file mode 100644 index 13d4b149651b..000000000000 --- a/src/main/resources/view/PersonListCard.fxml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/view/PersonListPanel.fxml b/src/main/resources/view/PersonListPanel.fxml deleted file mode 100644 index 000c4c999b65..000000000000 --- a/src/main/resources/view/PersonListPanel.fxml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/main/resources/view/ResultDisplay.fxml b/src/main/resources/view/ResultDisplay.fxml index cc650d739e22..60f6c8e54bfe 100644 --- a/src/main/resources/view/ResultDisplay.fxml +++ b/src/main/resources/view/ResultDisplay.fxml @@ -2,10 +2,10 @@ - - - - - + + + + + diff --git a/src/main/resources/view/StatusBarFooter.fxml b/src/main/resources/view/StatusBarFooter.fxml index 2656558b6eb7..651e469d51a2 100644 --- a/src/main/resources/view/StatusBarFooter.fxml +++ b/src/main/resources/view/StatusBarFooter.fxml @@ -1,13 +1,19 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/main/resources/view/TaskListCard.fxml b/src/main/resources/view/TaskListCard.fxml new file mode 100644 index 000000000000..fa1c100b4fc9 --- /dev/null +++ b/src/main/resources/view/TaskListCard.fxml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/TaskListPanel.fxml b/src/main/resources/view/TaskListPanel.fxml new file mode 100644 index 000000000000..3130fbf98fed --- /dev/null +++ b/src/main/resources/view/TaskListPanel.fxml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/src/test/data/ConfigUtilTest/ExtraValuesConfig.json b/src/test/data/ConfigUtilTest/ExtraValuesConfig.json index 578b4445204b..70640e9a1937 100644 --- a/src/test/data/ConfigUtilTest/ExtraValuesConfig.json +++ b/src/test/data/ConfigUtilTest/ExtraValuesConfig.json @@ -2,7 +2,7 @@ "appTitle" : "Typical App Title", "logLevel" : "INFO", "userPrefsFilePath" : "C:\\preferences.json", - "addressBookFilePath" : "addressbook.xml", - "addressBookName" : "TypicalAddressBookName", + "malitioFilePath" : "malitio.xml", + "malitioName" : "TypicalmalitioName", "extra" : "extra value" } \ No newline at end of file diff --git a/src/test/data/ConfigUtilTest/TypicalConfig.json b/src/test/data/ConfigUtilTest/TypicalConfig.json index 195b2bf33033..452bce52236c 100644 --- a/src/test/data/ConfigUtilTest/TypicalConfig.json +++ b/src/test/data/ConfigUtilTest/TypicalConfig.json @@ -2,6 +2,6 @@ "appTitle" : "Typical App Title", "logLevel" : "INFO", "userPrefsFilePath" : "C:\\preferences.json", - "addressBookFilePath" : "addressbook.xml", - "addressBookName" : "TypicalAddressBookName" + "malitioFilePath" : "malitio.xml", + "malitioName" : "TypicalmalitioName" } \ No newline at end of file diff --git a/src/test/data/XmlAddressBookStorageTest/NotXmlFormatAddressBook.xml b/src/test/data/XmlMalitioStorageTest/NotXmlFormatMalitio.xml similarity index 93% rename from src/test/data/XmlAddressBookStorageTest/NotXmlFormatAddressBook.xml rename to src/test/data/XmlMalitioStorageTest/NotXmlFormatMalitio.xml index 49d5d80d27a1..f1528c3ea675 100644 --- a/src/test/data/XmlAddressBookStorageTest/NotXmlFormatAddressBook.xml +++ b/src/test/data/XmlMalitioStorageTest/NotXmlFormatMalitio.xml @@ -1 +1,2 @@ + not xml format! \ No newline at end of file diff --git a/src/test/data/XmlUtilTest/tempAddressBook.xml b/src/test/data/XmlUtilTest/tempAddressBook.xml deleted file mode 100644 index 41eeb8eb391a..000000000000 --- a/src/test/data/XmlUtilTest/tempAddressBook.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - 1 - John - Doe - - - - - - - Friends - - diff --git a/src/test/data/XmlUtilTest/tempMalitio.xml b/src/test/data/XmlUtilTest/tempMalitio.xml new file mode 100644 index 000000000000..2bd83aa648fb --- /dev/null +++ b/src/test/data/XmlUtilTest/tempMalitio.xml @@ -0,0 +1,15 @@ + + + + 1 + John + Doe + + + + + + + Friends + + diff --git a/src/test/data/XmlUtilTest/validAddressBook.xml b/src/test/data/XmlUtilTest/validAddressBook.xml deleted file mode 100644 index eafca730fb1e..000000000000 --- a/src/test/data/XmlUtilTest/validAddressBook.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - Hans Muster - 9482424 - hans@google.com -
4th street
-
- - Ruth Mueller - 87249245 - ruth@google.com -
81th street
-
- - Heinz Kurz - 95352563 - heinz@yahoo.com -
wall street
-
- - Cornelia Meier - 87652533 - cornelia@google.com -
10th street
-
- - Werner Meyer - 9482224 - werner@gmail.com -
michegan ave
-
- - Lydia Kunz - 9482427 - lydia@gmail.com -
little tokyo
-
- - Anna Best - 9482442 - anna@google.com -
4th street
-
- - Stefan Meier - 8482424 - stefan@mail.com -
little india
-
- - Martin Mueller - 8482131 - hans@google.com -
chicago ave
-
-
diff --git a/src/test/data/XmlUtilTest/validMalitio.xml b/src/test/data/XmlUtilTest/validMalitio.xml new file mode 100644 index 000000000000..87888430b5ff --- /dev/null +++ b/src/test/data/XmlUtilTest/validMalitio.xml @@ -0,0 +1,30 @@ + + + + Hans Muster + + + Ruth Mueller + + + Heinz Kurz + + + Cornelia Meier + + + Werner Meyer + + + Lydia Kunz + + + Anna Best + + + Stefan Meier + + + Martin Mueller + + diff --git a/src/test/java/guitests/AddCommandTest.java b/src/test/java/guitests/AddCommandTest.java index 3b2e1844bd0d..79322bad81f4 100644 --- a/src/test/java/guitests/AddCommandTest.java +++ b/src/test/java/guitests/AddCommandTest.java @@ -1,53 +1,78 @@ package guitests; -import guitests.guihandles.PersonCardHandle; +import guitests.guihandles.TaskCardHandle; import org.junit.Test; -import seedu.address.logic.commands.AddCommand; -import seedu.address.commons.core.Messages; -import seedu.address.testutil.TestPerson; -import seedu.address.testutil.TestUtil; + +import seedu.malitio.testutil.TestTask; +import seedu.malitio.testutil.TestUtil; +import seedu.malitio.commons.core.Messages; +import seedu.malitio.logic.commands.AddCommand; import static org.junit.Assert.assertTrue; -public class AddCommandTest extends AddressBookGuiTest { +public class AddCommandTest extends MalitioGuiTest { @Test - public void add() { - //add one person - TestPerson[] currentList = td.getTypicalPersons(); - TestPerson personToAdd = td.hoon; - assertAddSuccess(personToAdd, currentList); - currentList = TestUtil.addPersonsToList(currentList, personToAdd); - - //add another person - personToAdd = td.ida; - assertAddSuccess(personToAdd, currentList); - currentList = TestUtil.addPersonsToList(currentList, personToAdd); - - //add duplicate person - commandBox.runCommand(td.hoon.getAddCommand()); - assertResultMessage(AddCommand.MESSAGE_DUPLICATE_PERSON); - assertTrue(personListPanel.isListMatching(currentList)); + public void addTask() { + //add one task + TestTask[] currentList = td.getTypicalTasks(); + TestTask taskToAdd = td.manualFloatingTask; + assertAddSuccess(taskToAdd, currentList); + currentList = TestUtil.addTasksToList(currentList, taskToAdd); + + //add another task + taskToAdd = td.manualDeadline; + assertAddSuccess(taskToAdd, currentList); + currentList = TestUtil.addTasksToList(currentList, taskToAdd); + + //add duplicate task + commandBox.runCommand(td.manualFloatingTask.getAddCommand()); + assertResultMessage(AddCommand.MESSAGE_DUPLICATE_TASK); + assertTrue(taskListPanel.isListMatching(currentList)); //add to empty list commandBox.runCommand("clear"); - assertAddSuccess(td.alice); + assertAddSuccess(td.floatingTask1); //invalid command - commandBox.runCommand("adds Johnny"); + commandBox.runCommand("adds run"); assertResultMessage(Messages.MESSAGE_UNKNOWN_COMMAND); } + + @Test + public void addDeadline() { + /* + //add one task + TestTask[] currentList = td.getTypicalTasks(); + TestTask taskToAdd = td.relax; + assertAddSuccess(taskToAdd, currentList); + currentList = TestUtil.addTasksToList(currentList, taskToAdd); + + //add another task + taskToAdd = td.prepare; + assertAddSuccess(taskToAdd, currentList); + currentList = TestUtil.addTasksToList(currentList, taskToAdd); + + //add duplicate task + commandBox.runCommand(td.relax.getAddCommand()); + assertResultMessage(AddCommand.MESSAGE_DUPLICATE_TASK); + assertTrue(taskListPanel.isListMatching(currentList)); + */ + //add to empty list + commandBox.runCommand("clear"); + assertAddSuccess(td.event4); + } - private void assertAddSuccess(TestPerson personToAdd, TestPerson... currentList) { - commandBox.runCommand(personToAdd.getAddCommand()); + private void assertAddSuccess(TestTask taskToAdd, TestTask... currentList) { + commandBox.runCommand(taskToAdd.getAddCommand()); //confirm the new card contains the right data - PersonCardHandle addedCard = personListPanel.navigateToPerson(personToAdd.getName().fullName); - assertMatching(personToAdd, addedCard); + TaskCardHandle addedCard = taskListPanel.navigateToTask(taskToAdd.getName().fullName); + assertMatching(taskToAdd, addedCard); - //confirm the list now contains all previous persons plus the new person - TestPerson[] expectedList = TestUtil.addPersonsToList(currentList, personToAdd); - assertTrue(personListPanel.isListMatching(expectedList)); + //confirm the list now contains all previous tasks plus the new task + TestTask[] expectedList = TestUtil.addTasksToList(currentList, taskToAdd); + assertTrue(taskListPanel.isListMatching(expectedList)); } } diff --git a/src/test/java/guitests/ClearCommandTest.java b/src/test/java/guitests/ClearCommandTest.java index 9d52b427659c..4189bee278b4 100644 --- a/src/test/java/guitests/ClearCommandTest.java +++ b/src/test/java/guitests/ClearCommandTest.java @@ -4,18 +4,18 @@ import static org.junit.Assert.assertTrue; -public class ClearCommandTest extends AddressBookGuiTest { +public class ClearCommandTest extends MalitioGuiTest { @Test public void clear() { //verify a non-empty list can be cleared - assertTrue(personListPanel.isListMatching(td.getTypicalPersons())); + assertTrue(taskListPanel.isListMatching(td.getTypicalTasks())); assertClearCommandSuccess(); //verify other commands can work after a clear command - commandBox.runCommand(td.hoon.getAddCommand()); - assertTrue(personListPanel.isListMatching(td.hoon)); + commandBox.runCommand(td.manualFloatingTask.getAddCommand()); + assertTrue(taskListPanel.isListMatching(td.manualFloatingTask)); commandBox.runCommand("delete 1"); assertListSize(0); @@ -26,6 +26,6 @@ public void clear() { private void assertClearCommandSuccess() { commandBox.runCommand("clear"); assertListSize(0); - assertResultMessage("Address book has been cleared!"); + assertResultMessage("Malitio has been cleared!"); } } diff --git a/src/test/java/guitests/CommandBoxTest.java b/src/test/java/guitests/CommandBoxTest.java index 1379198bf8b0..cb49af689edb 100644 --- a/src/test/java/guitests/CommandBoxTest.java +++ b/src/test/java/guitests/CommandBoxTest.java @@ -4,11 +4,11 @@ import static org.junit.Assert.assertEquals; -public class CommandBoxTest extends AddressBookGuiTest { +public class CommandBoxTest extends MalitioGuiTest { @Test public void commandBox_commandSucceeds_textCleared() { - commandBox.runCommand(td.benson.getAddCommand()); + commandBox.runCommand(td.floatingTask2.getAddCommand()); assertEquals(commandBox.getCommandInput(), ""); } diff --git a/src/test/java/guitests/DeleteCommandTest.java b/src/test/java/guitests/DeleteCommandTest.java index 10c7b9e0dbea..fff0f135c50a 100644 --- a/src/test/java/guitests/DeleteCommandTest.java +++ b/src/test/java/guitests/DeleteCommandTest.java @@ -1,54 +1,57 @@ package guitests; import org.junit.Test; -import seedu.address.testutil.TestPerson; -import seedu.address.testutil.TestUtil; +import seedu.malitio.testutil.TestTask; +import seedu.malitio.testutil.TestUtil; import static org.junit.Assert.assertTrue; -import static seedu.address.logic.commands.DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS; - -public class DeleteCommandTest extends AddressBookGuiTest { +import static seedu.malitio.logic.commands.DeleteCommand.MESSAGE_DELETE_TASK_SUCCESS; +public class DeleteCommandTest extends MalitioGuiTest { + + /** + * Uses boundary condition testing + */ @Test public void delete() { //delete the first in the list - TestPerson[] currentList = td.getTypicalPersons(); + TestTask[] currentList = td.getTypicalTasks(); int targetIndex = 1; assertDeleteSuccess(targetIndex, currentList); //delete the last in the list - currentList = TestUtil.removePersonFromList(currentList, targetIndex); + currentList = TestUtil.removeTaskFromList(currentList, targetIndex); targetIndex = currentList.length; assertDeleteSuccess(targetIndex, currentList); //delete from the middle of the list - currentList = TestUtil.removePersonFromList(currentList, targetIndex); + currentList = TestUtil.removeTaskFromList(currentList, targetIndex); targetIndex = currentList.length/2; assertDeleteSuccess(targetIndex, currentList); //invalid index commandBox.runCommand("delete " + currentList.length + 1); - assertResultMessage("The person index provided is invalid"); + assertResultMessage("The task index provided is invalid"); } /** - * Runs the delete command to delete the person at specified index and confirms the result is correct. - * @param targetIndexOneIndexed e.g. to delete the first person in the list, 1 should be given as the target index. - * @param currentList A copy of the current list of persons (before deletion). + * Runs the delete command to delete the task at specified index and confirms the result is correct. + * @param targetIndexOneIndexed e.g. to delete the first task in the list, 1 should be given as the target index. + * @param currentList A copy of the current list of tasks (before deletion). */ - private void assertDeleteSuccess(int targetIndexOneIndexed, final TestPerson[] currentList) { - TestPerson personToDelete = currentList[targetIndexOneIndexed-1]; //-1 because array uses zero indexing - TestPerson[] expectedRemainder = TestUtil.removePersonFromList(currentList, targetIndexOneIndexed); + private void assertDeleteSuccess(int targetIndexOneIndexed, final TestTask[] currentList) { + TestTask taskToDelete = currentList[targetIndexOneIndexed-1]; //-1 because array uses zero indexing + TestTask[] expectedRemainder = TestUtil.removeTaskFromList(currentList, targetIndexOneIndexed); commandBox.runCommand("delete " + targetIndexOneIndexed); - //confirm the list now contains all previous persons except the deleted person - assertTrue(personListPanel.isListMatching(expectedRemainder)); + //confirm the list now contains all previous tasks except the deleted task + assertTrue(taskListPanel.isListMatching(expectedRemainder)); //confirm the result message is correct - assertResultMessage(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete)); + assertResultMessage(String.format(MESSAGE_DELETE_TASK_SUCCESS, taskToDelete)); } } diff --git a/src/test/java/guitests/FindCommandTest.java b/src/test/java/guitests/FindCommandTest.java index 441a6dbed666..4c5863697157 100644 --- a/src/test/java/guitests/FindCommandTest.java +++ b/src/test/java/guitests/FindCommandTest.java @@ -1,39 +1,40 @@ package guitests; import org.junit.Test; -import seedu.address.commons.core.Messages; -import seedu.address.testutil.TestPerson; + +import seedu.malitio.testutil.TestTask; +import seedu.malitio.commons.core.Messages; import static org.junit.Assert.assertTrue; -public class FindCommandTest extends AddressBookGuiTest { +public class FindCommandTest extends MalitioGuiTest { @Test public void find_nonEmptyList() { - assertFindResult("find Mark"); //no results - assertFindResult("find Meier", td.benson, td.daniel); //multiple results + assertFindResult("find jump"); //no results + assertFindResult("find with", td.event1, td.event2); //multiple results //find after deleting one result commandBox.runCommand("delete 1"); - assertFindResult("find Meier",td.daniel); + assertFindResult("find meter",td.floatingTask1); } @Test public void find_emptyList(){ commandBox.runCommand("clear"); - assertFindResult("find Jean"); //no results + assertFindResult("find eat"); //no results } @Test public void find_invalidCommand_fail() { - commandBox.runCommand("findgeorge"); + commandBox.runCommand("finddonothing"); assertResultMessage(Messages.MESSAGE_UNKNOWN_COMMAND); } - private void assertFindResult(String command, TestPerson... expectedHits ) { + private void assertFindResult(String command, TestTask... expectedHits ) { commandBox.runCommand(command); assertListSize(expectedHits.length); - assertResultMessage(expectedHits.length + " persons listed!"); - assertTrue(personListPanel.isListMatching(expectedHits)); + assertResultMessage(expectedHits.length + " tasks listed!"); + assertTrue(taskListPanel.isListMatching(expectedHits)); } } diff --git a/src/test/java/guitests/GuiRobot.java b/src/test/java/guitests/GuiRobot.java index 44aa9edb48aa..eec321d58e14 100644 --- a/src/test/java/guitests/GuiRobot.java +++ b/src/test/java/guitests/GuiRobot.java @@ -2,7 +2,7 @@ import javafx.scene.input.KeyCodeCombination; import org.testfx.api.FxRobot; -import seedu.address.testutil.TestUtil; +import seedu.malitio.testutil.TestUtil; /** * Robot used to simulate user actions on the GUI. diff --git a/src/test/java/guitests/HelpWindowTest.java b/src/test/java/guitests/HelpWindowTest.java index 258d9d628d80..801a99c24143 100644 --- a/src/test/java/guitests/HelpWindowTest.java +++ b/src/test/java/guitests/HelpWindowTest.java @@ -5,12 +5,12 @@ import static org.junit.Assert.assertTrue; -public class HelpWindowTest extends AddressBookGuiTest { +public class HelpWindowTest extends MalitioGuiTest { @Test public void openHelpWindow() { - personListPanel.clickOnListView(); + taskListPanel.clickOnListView(); assertHelpWindowOpen(mainMenu.openHelpWindowUsingAccelerator()); diff --git a/src/test/java/guitests/AddressBookGuiTest.java b/src/test/java/guitests/MalitioGuiTest.java similarity index 71% rename from src/test/java/guitests/AddressBookGuiTest.java rename to src/test/java/guitests/MalitioGuiTest.java index 35734932f11c..deea85f9fe6c 100644 --- a/src/test/java/guitests/AddressBookGuiTest.java +++ b/src/test/java/guitests/MalitioGuiTest.java @@ -8,12 +8,12 @@ import org.junit.Rule; import org.junit.rules.TestName; import org.testfx.api.FxToolkit; -import seedu.address.TestApp; -import seedu.address.commons.core.EventsCenter; -import seedu.address.model.AddressBook; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.testutil.TestUtil; -import seedu.address.testutil.TypicalTestPersons; +import seedu.malitio.TestApp; +import seedu.malitio.testutil.TestUtil; +import seedu.malitio.testutil.TypicalTestTasks; +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.model.Malitio; +import seedu.malitio.model.task.ReadOnlyFloatingTask; import java.util.concurrent.TimeoutException; @@ -21,9 +21,9 @@ import static org.junit.Assert.assertTrue; /** - * A GUI Test class for AddressBook. + * A GUI Test class for malitio. */ -public abstract class AddressBookGuiTest { +public abstract class MalitioGuiTest { /* The TestName Rule makes the current test name available inside test methods */ @Rule @@ -31,7 +31,7 @@ public abstract class AddressBookGuiTest { TestApp testApp; - protected TypicalTestPersons td = new TypicalTestPersons(); + protected TypicalTestTasks td = new TypicalTestTasks(); /* * Handles to GUI elements present at the start up are created in advance @@ -39,7 +39,7 @@ public abstract class AddressBookGuiTest { */ protected MainGuiHandle mainGui; protected MainMenuHandle mainMenu; - protected PersonListPanelHandle personListPanel; + protected TaskListPanelHandle taskListPanel; protected ResultDisplayHandle resultDisplay; protected CommandBoxHandle commandBox; private Stage stage; @@ -59,7 +59,7 @@ public void setup() throws Exception { FxToolkit.setupStage((stage) -> { mainGui = new MainGuiHandle(new GuiRobot(), stage); mainMenu = mainGui.getMainMenu(); - personListPanel = mainGui.getPersonListPanel(); + taskListPanel = mainGui.getTaskListPanel(); resultDisplay = mainGui.getResultDisplay(); commandBox = mainGui.getCommandBox(); this.stage = stage; @@ -75,9 +75,9 @@ public void setup() throws Exception { * Override this in child classes to set the initial local data. * Return null to use the data in the file specified in {@link #getDataFileLocation()} */ - protected AddressBook getInitialData() { - AddressBook ab = TestUtil.generateEmptyAddressBook(); - TypicalTestPersons.loadAddressBookWithSampleData(ab); + protected Malitio getInitialData() { + Malitio ab = TestUtil.generateEmptymalitio(); + TypicalTestTasks.loadmalitioWithSampleData(ab); return ab; } @@ -94,17 +94,17 @@ public void cleanup() throws TimeoutException { } /** - * Asserts the person shown in the card is same as the given person + * Asserts the task shown in the card is same as the given task */ - public void assertMatching(ReadOnlyPerson person, PersonCardHandle card) { - assertTrue(TestUtil.compareCardAndPerson(card, person)); + public void assertMatching(ReadOnlyFloatingTask task, TaskCardHandle card) { + assertTrue(TestUtil.compareCardAndTask(card, task)); } /** - * Asserts the size of the person list is equal to the given number. + * Asserts the size of the task list is equal to the given number. */ protected void assertListSize(int size) { - int numberOfPeople = personListPanel.getNumberOfPeople(); + int numberOfPeople = taskListPanel.getNumberOfPeople(); assertEquals(size, numberOfPeople); } diff --git a/src/test/java/guitests/SelectCommandTest.java b/src/test/java/guitests/SelectCommandTest.java index 5273552056ce..a1e8635380f3 100644 --- a/src/test/java/guitests/SelectCommandTest.java +++ b/src/test/java/guitests/SelectCommandTest.java @@ -1,33 +1,34 @@ package guitests; import org.junit.Test; -import seedu.address.model.person.ReadOnlyPerson; + +import seedu.malitio.model.task.ReadOnlyFloatingTask; import static org.junit.Assert.assertEquals; -public class SelectCommandTest extends AddressBookGuiTest { +public class SelectCommandTest extends MalitioGuiTest { @Test - public void selectPerson_nonEmptyList() { + public void selectTask_nonEmptyList() { assertSelectionInvalid(10); //invalid index - assertNoPersonSelected(); + assertNoTaskSelected(); - assertSelectionSuccess(1); //first person in the list - int personCount = td.getTypicalPersons().length; - assertSelectionSuccess(personCount); //last person in the list - int middleIndex = personCount / 2; - assertSelectionSuccess(middleIndex); //a person in the middle of the list + assertSelectionSuccess(1); //first task in the list + int taskCount = td.getTypicalTasks().length; + assertSelectionSuccess(taskCount); //last task in the list + int middleIndex = taskCount / 2; + assertSelectionSuccess(middleIndex); //a task in the middle of the list - assertSelectionInvalid(personCount + 1); //invalid index - assertPersonSelected(middleIndex); //assert previous selection remains + assertSelectionInvalid(taskCount + 1); //invalid index + assertTaskSelected(middleIndex); //assert previous selection remains /* Testing other invalid indexes such as -1 should be done when testing the SelectCommand */ } @Test - public void selectPerson_emptyList(){ + public void selectTask_emptyList(){ commandBox.runCommand("clear"); assertListSize(0); assertSelectionInvalid(1); //invalid index @@ -35,24 +36,24 @@ public void selectPerson_emptyList(){ private void assertSelectionInvalid(int index) { commandBox.runCommand("select " + index); - assertResultMessage("The person index provided is invalid"); + assertResultMessage("The task index provided is invalid"); } private void assertSelectionSuccess(int index) { commandBox.runCommand("select " + index); - assertResultMessage("Selected Person: "+index); - assertPersonSelected(index); + assertResultMessage("Selected Task: "+index); + assertTaskSelected(index); } - private void assertPersonSelected(int index) { - assertEquals(personListPanel.getSelectedPersons().size(), 1); - ReadOnlyPerson selectedPerson = personListPanel.getSelectedPersons().get(0); - assertEquals(personListPanel.getPerson(index-1), selectedPerson); + private void assertTaskSelected(int index) { + assertEquals(taskListPanel.getSelectedTasks().size(), 1); + ReadOnlyFloatingTask selectedTask = taskListPanel.getSelectedTasks().get(0); + assertEquals(taskListPanel.getTask(index-1), selectedTask); //TODO: confirm the correct page is loaded in the Browser Panel } - private void assertNoPersonSelected() { - assertEquals(personListPanel.getSelectedPersons().size(), 0); + private void assertNoTaskSelected() { + assertEquals(taskListPanel.getSelectedTasks().size(), 0); } } diff --git a/src/test/java/guitests/guihandles/GuiHandle.java b/src/test/java/guitests/guihandles/GuiHandle.java index 5e7e0f6de911..a64b72de370c 100644 --- a/src/test/java/guitests/guihandles/GuiHandle.java +++ b/src/test/java/guitests/guihandles/GuiHandle.java @@ -7,8 +7,8 @@ import javafx.scene.input.KeyCode; import javafx.stage.Stage; import javafx.stage.Window; -import seedu.address.TestApp; -import seedu.address.commons.core.LogsCenter; +import seedu.malitio.TestApp; +import seedu.malitio.commons.core.LogsCenter; import java.util.logging.Logger; diff --git a/src/test/java/guitests/guihandles/MainGuiHandle.java b/src/test/java/guitests/guihandles/MainGuiHandle.java index 45802c5135c7..b7c5db2437d7 100644 --- a/src/test/java/guitests/guihandles/MainGuiHandle.java +++ b/src/test/java/guitests/guihandles/MainGuiHandle.java @@ -2,7 +2,7 @@ import guitests.GuiRobot; import javafx.stage.Stage; -import seedu.address.TestApp; +import seedu.malitio.TestApp; /** * Provides a handle for the main GUI. @@ -13,8 +13,8 @@ public MainGuiHandle(GuiRobot guiRobot, Stage primaryStage) { super(guiRobot, primaryStage, TestApp.APP_TITLE); } - public PersonListPanelHandle getPersonListPanel() { - return new PersonListPanelHandle(guiRobot, primaryStage); + public TaskListPanelHandle getTaskListPanel() { + return new TaskListPanelHandle(guiRobot, primaryStage); } public ResultDisplayHandle getResultDisplay() { diff --git a/src/test/java/guitests/guihandles/MainMenuHandle.java b/src/test/java/guitests/guihandles/MainMenuHandle.java index 0aeb047a0e1d..b2e984782667 100644 --- a/src/test/java/guitests/guihandles/MainMenuHandle.java +++ b/src/test/java/guitests/guihandles/MainMenuHandle.java @@ -3,7 +3,7 @@ import guitests.GuiRobot; import javafx.scene.input.KeyCode; import javafx.stage.Stage; -import seedu.address.TestApp; +import seedu.malitio.TestApp; import java.util.Arrays; diff --git a/src/test/java/guitests/guihandles/PersonCardHandle.java b/src/test/java/guitests/guihandles/PersonCardHandle.java deleted file mode 100644 index fae22a45ae2f..000000000000 --- a/src/test/java/guitests/guihandles/PersonCardHandle.java +++ /dev/null @@ -1,63 +0,0 @@ -package guitests.guihandles; - -import guitests.GuiRobot; -import javafx.scene.Node; -import javafx.stage.Stage; -import seedu.address.model.person.ReadOnlyPerson; - -/** - * Provides a handle to a person card in the person list panel. - */ -public class PersonCardHandle extends GuiHandle { - private static final String NAME_FIELD_ID = "#name"; - private static final String ADDRESS_FIELD_ID = "#address"; - private static final String PHONE_FIELD_ID = "#phone"; - private static final String EMAIL_FIELD_ID = "#email"; - - private Node node; - - public PersonCardHandle(GuiRobot guiRobot, Stage primaryStage, Node node){ - super(guiRobot, primaryStage, null); - this.node = node; - } - - protected String getTextFromLabel(String fieldId) { - return getTextFromLabel(fieldId, node); - } - - public String getFullName() { - return getTextFromLabel(NAME_FIELD_ID); - } - - public String getAddress() { - return getTextFromLabel(ADDRESS_FIELD_ID); - } - - public String getPhone() { - return getTextFromLabel(PHONE_FIELD_ID); - } - - public String getEmail() { - return getTextFromLabel(EMAIL_FIELD_ID); - } - - public boolean isSamePerson(ReadOnlyPerson person){ - return getFullName().equals(person.getName().fullName) && getPhone().equals(person.getPhone().value) - && getEmail().equals(person.getEmail().value) && getAddress().equals(person.getAddress().value); - } - - @Override - public boolean equals(Object obj) { - if(obj instanceof PersonCardHandle) { - PersonCardHandle handle = (PersonCardHandle) obj; - return getFullName().equals(handle.getFullName()) - && getAddress().equals(handle.getAddress()); //TODO: compare the rest - } - return super.equals(obj); - } - - @Override - public String toString() { - return getFullName() + " " + getAddress(); - } -} diff --git a/src/test/java/guitests/guihandles/PersonListPanelHandle.java b/src/test/java/guitests/guihandles/PersonListPanelHandle.java deleted file mode 100644 index 3451992cf735..000000000000 --- a/src/test/java/guitests/guihandles/PersonListPanelHandle.java +++ /dev/null @@ -1,172 +0,0 @@ -package guitests.guihandles; - - -import guitests.GuiRobot; -import javafx.geometry.Point2D; -import javafx.scene.Node; -import javafx.scene.control.ListView; -import javafx.stage.Stage; -import seedu.address.TestApp; -import seedu.address.model.person.Person; -import seedu.address.model.person.ReadOnlyPerson; -import seedu.address.testutil.TestUtil; - -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import static org.junit.Assert.assertTrue; - -/** - * Provides a handle for the panel containing the person list. - */ -public class PersonListPanelHandle extends GuiHandle { - - public static final int NOT_FOUND = -1; - public static final String CARD_PANE_ID = "#cardPane"; - - private static final String PERSON_LIST_VIEW_ID = "#personListView"; - - public PersonListPanelHandle(GuiRobot guiRobot, Stage primaryStage) { - super(guiRobot, primaryStage, TestApp.APP_TITLE); - } - - public List getSelectedPersons() { - ListView personList = getListView(); - return personList.getSelectionModel().getSelectedItems(); - } - - public ListView getListView() { - return (ListView) getNode(PERSON_LIST_VIEW_ID); - } - - /** - * Returns true if the list is showing the person details correctly and in correct order. - * @param persons A list of person in the correct order. - */ - public boolean isListMatching(ReadOnlyPerson... persons) { - return this.isListMatching(0, persons); - } - - /** - * Clicks on the ListView. - */ - public void clickOnListView() { - Point2D point= TestUtil.getScreenMidPoint(getListView()); - guiRobot.clickOn(point.getX(), point.getY()); - } - - /** - * Returns true if the {@code persons} appear as the sub list (in that order) at position {@code startPosition}. - */ - public boolean containsInOrder(int startPosition, ReadOnlyPerson... persons) { - List personsInList = getListView().getItems(); - - // Return false if the list in panel is too short to contain the given list - if (startPosition + persons.length > personsInList.size()){ - return false; - } - - // Return false if any of the persons doesn't match - for (int i = 0; i < persons.length; i++) { - if (!personsInList.get(startPosition + i).getName().fullName.equals(persons[i].getName().fullName)){ - return false; - } - } - - return true; - } - - /** - * Returns true if the list is showing the person details correctly and in correct order. - * @param startPosition The starting position of the sub list. - * @param persons A list of person in the correct order. - */ - public boolean isListMatching(int startPosition, ReadOnlyPerson... persons) throws IllegalArgumentException { - if (persons.length + startPosition != getListView().getItems().size()) { - throw new IllegalArgumentException("List size mismatched\n" + - "Expected " + (getListView().getItems().size() - 1) + " persons"); - } - assertTrue(this.containsInOrder(startPosition, persons)); - for (int i = 0; i < persons.length; i++) { - final int scrollTo = i + startPosition; - guiRobot.interact(() -> getListView().scrollTo(scrollTo)); - guiRobot.sleep(200); - if (!TestUtil.compareCardAndPerson(getPersonCardHandle(startPosition + i), persons[i])) { - return false; - } - } - return true; - } - - - public PersonCardHandle navigateToPerson(String name) { - guiRobot.sleep(500); //Allow a bit of time for the list to be updated - final Optional person = getListView().getItems().stream().filter(p -> p.getName().fullName.equals(name)).findAny(); - if (!person.isPresent()) { - throw new IllegalStateException("Name not found: " + name); - } - - return navigateToPerson(person.get()); - } - - /** - * Navigates the listview to display and select the person. - */ - public PersonCardHandle navigateToPerson(ReadOnlyPerson person) { - int index = getPersonIndex(person); - - guiRobot.interact(() -> { - getListView().scrollTo(index); - guiRobot.sleep(150); - getListView().getSelectionModel().select(index); - }); - guiRobot.sleep(100); - return getPersonCardHandle(person); - } - - - /** - * Returns the position of the person given, {@code NOT_FOUND} if not found in the list. - */ - public int getPersonIndex(ReadOnlyPerson targetPerson) { - List personsInList = getListView().getItems(); - for (int i = 0; i < personsInList.size(); i++) { - if(personsInList.get(i).getName().equals(targetPerson.getName())){ - return i; - } - } - return NOT_FOUND; - } - - /** - * Gets a person from the list by index - */ - public ReadOnlyPerson getPerson(int index) { - return getListView().getItems().get(index); - } - - public PersonCardHandle getPersonCardHandle(int index) { - return getPersonCardHandle(new Person(getListView().getItems().get(index))); - } - - public PersonCardHandle getPersonCardHandle(ReadOnlyPerson person) { - Set nodes = getAllCardNodes(); - Optional personCardNode = nodes.stream() - .filter(n -> new PersonCardHandle(guiRobot, primaryStage, n).isSamePerson(person)) - .findFirst(); - if (personCardNode.isPresent()) { - return new PersonCardHandle(guiRobot, primaryStage, personCardNode.get()); - } else { - return null; - } - } - - protected Set getAllCardNodes() { - return guiRobot.lookup(CARD_PANE_ID).queryAll(); - } - - public int getNumberOfPeople() { - return getListView().getItems().size(); - } -} diff --git a/src/test/java/guitests/guihandles/ResultDisplayHandle.java b/src/test/java/guitests/guihandles/ResultDisplayHandle.java index 110b4682b184..212804c078dd 100644 --- a/src/test/java/guitests/guihandles/ResultDisplayHandle.java +++ b/src/test/java/guitests/guihandles/ResultDisplayHandle.java @@ -3,7 +3,7 @@ import guitests.GuiRobot; import javafx.scene.control.TextArea; import javafx.stage.Stage; -import seedu.address.TestApp; +import seedu.malitio.TestApp; /** * A handler for the ResultDisplay of the UI diff --git a/src/test/java/guitests/guihandles/TaskCardHandle.java b/src/test/java/guitests/guihandles/TaskCardHandle.java new file mode 100644 index 000000000000..39c55d5ac490 --- /dev/null +++ b/src/test/java/guitests/guihandles/TaskCardHandle.java @@ -0,0 +1,46 @@ +package guitests.guihandles; + +import guitests.GuiRobot; +import javafx.scene.Node; +import javafx.stage.Stage; +import seedu.malitio.model.task.ReadOnlyFloatingTask; + +/** + * Provides a handle to a task card in the task list panel. + */ +public class TaskCardHandle extends GuiHandle { + private static final String NAME_FIELD_ID = "#name"; + + private Node node; + + public TaskCardHandle(GuiRobot guiRobot, Stage primaryStage, Node node){ + super(guiRobot, primaryStage, null); + this.node = node; + } + + protected String getTextFromLabel(String fieldId) { + return getTextFromLabel(fieldId, node); + } + + public String getFullName() { + return getTextFromLabel(NAME_FIELD_ID); + } + + public boolean isSameTask(ReadOnlyFloatingTask task){ + return getFullName().equals(task.getName().fullName); + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof TaskCardHandle) { + TaskCardHandle handle = (TaskCardHandle) obj; + return getFullName().equals(handle.getFullName()); + } + return super.equals(obj); + } + + @Override + public String toString() { + return getFullName(); + } +} diff --git a/src/test/java/guitests/guihandles/TaskListPanelHandle.java b/src/test/java/guitests/guihandles/TaskListPanelHandle.java new file mode 100644 index 000000000000..0df731b7be77 --- /dev/null +++ b/src/test/java/guitests/guihandles/TaskListPanelHandle.java @@ -0,0 +1,171 @@ +package guitests.guihandles; + + +import guitests.GuiRobot; +import javafx.geometry.Point2D; +import javafx.scene.Node; +import javafx.scene.control.ListView; +import javafx.stage.Stage; +import seedu.malitio.TestApp; +import seedu.malitio.testutil.TestUtil; +import seedu.malitio.model.task.FloatingTask; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static org.junit.Assert.assertTrue; + +/** + * Provides a handle for the panel containing the task list. + */ +public class TaskListPanelHandle extends GuiHandle { + + public static final int NOT_FOUND = -1; + public static final String CARD_PANE_ID = "#cardPane"; + + private static final String TASK_LIST_VIEW_ID = "#taskListView"; + + public TaskListPanelHandle(GuiRobot guiRobot, Stage primaryStage) { + super(guiRobot, primaryStage, TestApp.APP_TITLE); + } + + public List getSelectedTasks() { + ListView taskList = getListView(); + return taskList.getSelectionModel().getSelectedItems(); + } + + public ListView getListView() { + return (ListView) getNode(TASK_LIST_VIEW_ID); + } + + /** + * Returns true if the list is showing the task details correctly and in correct order. + * @param tasks A list of task in the correct order. + */ + public boolean isListMatching(ReadOnlyFloatingTask... tasks) { + return this.isListMatching(0, tasks); + } + + /** + * Clicks on the ListView. + */ + public void clickOnListView() { + Point2D point= TestUtil.getScreenMidPoint(getListView()); + guiRobot.clickOn(point.getX(), point.getY()); + } + + /** + * Returns true if the {@code tasks} appear as the sub list (in that order) at position {@code startPosition}. + */ + public boolean containsInOrder(int startPosition, ReadOnlyFloatingTask... tasks) { + List tasksInList = getListView().getItems(); + + // Return false if the list in panel is too short to contain the given list + if (startPosition + tasks.length > tasksInList.size()){ + return false; + } + + // Return false if any of the tasks doesn't match + for (int i = 0; i < tasks.length; i++) { + if (!tasksInList.get(startPosition + i).getName().fullName.equals(tasks[i].getName().fullName)){ + return false; + } + } + + return true; + } + + /** + * Returns true if the list is showing the task details correctly and in correct order. + * @param startPosition The starting position of the sub list. + * @param tasks A list of task in the correct order. + */ + public boolean isListMatching(int startPosition, ReadOnlyFloatingTask... tasks) throws IllegalArgumentException { + if (tasks.length + startPosition != getListView().getItems().size()) { + throw new IllegalArgumentException("List size mismatched\n" + + "Expected " + (getListView().getItems().size() - 1) + " tasks"); + } + assertTrue(this.containsInOrder(startPosition, tasks)); + for (int i = 0; i < tasks.length; i++) { + final int scrollTo = i + startPosition; + guiRobot.interact(() -> getListView().scrollTo(scrollTo)); + guiRobot.sleep(200); + if (!TestUtil.compareCardAndTask(getTaskCardHandle(startPosition + i), tasks[i])) { + return false; + } + } + return true; + } + + + public TaskCardHandle navigateToTask(String name) { + guiRobot.sleep(500); //Allow a bit of time for the list to be updated + final Optional task = getListView().getItems().stream().filter(p -> p.getName().fullName.equals(name)).findAny(); + if (!task.isPresent()) { + throw new IllegalStateException("Name not found: " + name); + } + + return navigateToTask(task.get()); + } + + /** + * Navigates the listview to display and select the task. + */ + public TaskCardHandle navigateToTask(ReadOnlyFloatingTask task) { + int index = getTaskIndex(task); + + guiRobot.interact(() -> { + getListView().scrollTo(index); + guiRobot.sleep(150); + getListView().getSelectionModel().select(index); + }); + guiRobot.sleep(100); + return getTaskCardHandle(task); + } + + + /** + * Returns the position of the task given, {@code NOT_FOUND} if not found in the list. + */ + public int getTaskIndex(ReadOnlyFloatingTask targetTask) { + List tasksInList = getListView().getItems(); + for (int i = 0; i < tasksInList.size(); i++) { + if(tasksInList.get(i).getName().equals(targetTask.getName())){ + return i; + } + } + return NOT_FOUND; + } + + /** + * Gets a task from the list by index + */ + public ReadOnlyFloatingTask getTask(int index) { + return getListView().getItems().get(index); + } + + public TaskCardHandle getTaskCardHandle(int index) { + return getTaskCardHandle(new FloatingTask(getListView().getItems().get(index))); + } + + public TaskCardHandle getTaskCardHandle(ReadOnlyFloatingTask task) { + Set nodes = getAllCardNodes(); + Optional taskCardNode = nodes.stream() + .filter(n -> new TaskCardHandle(guiRobot, primaryStage, n).isSameTask(task)) + .findFirst(); + if (taskCardNode.isPresent()) { + return new TaskCardHandle(guiRobot, primaryStage, taskCardNode.get()); + } else { + return null; + } + } + + protected Set getAllCardNodes() { + return guiRobot.lookup(CARD_PANE_ID).queryAll(); + } + + public int getNumberOfPeople() { + return getListView().getItems().size(); + } +} diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java deleted file mode 100644 index e1ee0cfb4051..000000000000 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ /dev/null @@ -1,512 +0,0 @@ -package seedu.address.logic; - -import com.google.common.eventbus.Subscribe; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import seedu.address.commons.core.EventsCenter; -import seedu.address.logic.commands.*; -import seedu.address.commons.events.ui.JumpToListRequestEvent; -import seedu.address.commons.events.ui.ShowHelpRequestEvent; -import seedu.address.commons.events.model.AddressBookChangedEvent; -import seedu.address.model.AddressBook; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.*; -import seedu.address.model.tag.Tag; -import seedu.address.model.tag.UniqueTagList; -import seedu.address.storage.StorageManager; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static seedu.address.commons.core.Messages.*; - -public class LogicManagerTest { - - /** - * See https://github.com/junit-team/junit4/wiki/rules#temporaryfolder-rule - */ - @Rule - public TemporaryFolder saveFolder = new TemporaryFolder(); - - private Model model; - private Logic logic; - - //These are for checking the correctness of the events raised - private ReadOnlyAddressBook latestSavedAddressBook; - private boolean helpShown; - private int targetedJumpIndex; - - @Subscribe - private void handleLocalModelChangedEvent(AddressBookChangedEvent abce) { - latestSavedAddressBook = new AddressBook(abce.data); - } - - @Subscribe - private void handleShowHelpRequestEvent(ShowHelpRequestEvent she) { - helpShown = true; - } - - @Subscribe - private void handleJumpToListRequestEvent(JumpToListRequestEvent je) { - targetedJumpIndex = je.targetIndex; - } - - @Before - public void setup() { - model = new ModelManager(); - String tempAddressBookFile = saveFolder.getRoot().getPath() + "TempAddressBook.xml"; - String tempPreferencesFile = saveFolder.getRoot().getPath() + "TempPreferences.json"; - logic = new LogicManager(model, new StorageManager(tempAddressBookFile, tempPreferencesFile)); - EventsCenter.getInstance().registerHandler(this); - - latestSavedAddressBook = new AddressBook(model.getAddressBook()); // last saved assumed to be up to date before. - helpShown = false; - targetedJumpIndex = -1; // non yet - } - - @After - public void teardown() { - EventsCenter.clearSubscribers(); - } - - @Test - public void execute_invalid() throws Exception { - String invalidCommand = " "; - assertCommandBehavior(invalidCommand, - String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE)); - } - - /** - * Executes the command and confirms that the result message is correct. - * Both the 'address book' and the 'last shown list' are expected to be empty. - * @see #assertCommandBehavior(String, String, ReadOnlyAddressBook, List) - */ - private void assertCommandBehavior(String inputCommand, String expectedMessage) throws Exception { - assertCommandBehavior(inputCommand, expectedMessage, new AddressBook(), Collections.emptyList()); - } - - /** - * Executes the command and confirms that the result message is correct and - * also confirms that the following three parts of the LogicManager object's state are as expected:
- * - the internal address book data are same as those in the {@code expectedAddressBook}
- * - the backing list shown by UI matches the {@code shownList}
- * - {@code expectedAddressBook} was saved to the storage file.
- */ - private void assertCommandBehavior(String inputCommand, String expectedMessage, - ReadOnlyAddressBook expectedAddressBook, - List expectedShownList) throws Exception { - - //Execute the command - CommandResult result = logic.execute(inputCommand); - - //Confirm the ui display elements should contain the right data - assertEquals(expectedMessage, result.feedbackToUser); - assertEquals(expectedShownList, model.getFilteredPersonList()); - - //Confirm the state of data (saved and in-memory) is as expected - assertEquals(expectedAddressBook, model.getAddressBook()); - assertEquals(expectedAddressBook, latestSavedAddressBook); - } - - - @Test - public void execute_unknownCommandWord() throws Exception { - String unknownCommand = "uicfhmowqewca"; - assertCommandBehavior(unknownCommand, MESSAGE_UNKNOWN_COMMAND); - } - - @Test - public void execute_help() throws Exception { - assertCommandBehavior("help", HelpCommand.SHOWING_HELP_MESSAGE); - assertTrue(helpShown); - } - - @Test - public void execute_exit() throws Exception { - assertCommandBehavior("exit", ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT); - } - - @Test - public void execute_clear() throws Exception { - TestDataHelper helper = new TestDataHelper(); - model.addPerson(helper.generatePerson(1)); - model.addPerson(helper.generatePerson(2)); - model.addPerson(helper.generatePerson(3)); - - assertCommandBehavior("clear", ClearCommand.MESSAGE_SUCCESS, new AddressBook(), Collections.emptyList()); - } - - - @Test - public void execute_add_invalidArgsFormat() throws Exception { - String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE); - assertCommandBehavior( - "add wrong args wrong args", expectedMessage); - assertCommandBehavior( - "add Valid Name 12345 e/valid@email.butNoPhonePrefix a/valid, address", expectedMessage); - assertCommandBehavior( - "add Valid Name p/12345 valid@email.butNoPrefix a/valid, address", expectedMessage); - assertCommandBehavior( - "add Valid Name p/12345 e/valid@email.butNoAddressPrefix valid, address", expectedMessage); - } - - @Test - public void execute_add_invalidPersonData() throws Exception { - assertCommandBehavior( - "add []\\[;] p/12345 e/valid@e.mail a/valid, address", Name.MESSAGE_NAME_CONSTRAINTS); - assertCommandBehavior( - "add Valid Name p/not_numbers e/valid@e.mail a/valid, address", Phone.MESSAGE_PHONE_CONSTRAINTS); - assertCommandBehavior( - "add Valid Name p/12345 e/notAnEmail a/valid, address", Email.MESSAGE_EMAIL_CONSTRAINTS); - assertCommandBehavior( - "add Valid Name p/12345 e/valid@e.mail a/valid, address t/invalid_-[.tag", Tag.MESSAGE_TAG_CONSTRAINTS); - - } - - @Test - public void execute_add_successful() throws Exception { - // setup expectations - TestDataHelper helper = new TestDataHelper(); - Person toBeAdded = helper.adam(); - AddressBook expectedAB = new AddressBook(); - expectedAB.addPerson(toBeAdded); - - // execute command and verify result - assertCommandBehavior(helper.generateAddCommand(toBeAdded), - String.format(AddCommand.MESSAGE_SUCCESS, toBeAdded), - expectedAB, - expectedAB.getPersonList()); - - } - - @Test - public void execute_addDuplicate_notAllowed() throws Exception { - // setup expectations - TestDataHelper helper = new TestDataHelper(); - Person toBeAdded = helper.adam(); - AddressBook expectedAB = new AddressBook(); - expectedAB.addPerson(toBeAdded); - - // setup starting state - model.addPerson(toBeAdded); // person already in internal address book - - // execute command and verify result - assertCommandBehavior( - helper.generateAddCommand(toBeAdded), - AddCommand.MESSAGE_DUPLICATE_PERSON, - expectedAB, - expectedAB.getPersonList()); - - } - - - @Test - public void execute_list_showsAllPersons() throws Exception { - // prepare expectations - TestDataHelper helper = new TestDataHelper(); - AddressBook expectedAB = helper.generateAddressBook(2); - List expectedList = expectedAB.getPersonList(); - - // prepare address book state - helper.addToModel(model, 2); - - assertCommandBehavior("list", - ListCommand.MESSAGE_SUCCESS, - expectedAB, - expectedList); - } - - - /** - * Confirms the 'invalid argument index number behaviour' for the given command - * targeting a single person in the shown list, using visible index. - * @param commandWord to test assuming it targets a single person in the last shown list based on visible index. - */ - private void assertIncorrectIndexFormatBehaviorForCommand(String commandWord, String expectedMessage) throws Exception { - assertCommandBehavior(commandWord , expectedMessage); //index missing - assertCommandBehavior(commandWord + " +1", expectedMessage); //index should be unsigned - assertCommandBehavior(commandWord + " -1", expectedMessage); //index should be unsigned - assertCommandBehavior(commandWord + " 0", expectedMessage); //index cannot be 0 - assertCommandBehavior(commandWord + " not_a_number", expectedMessage); - } - - /** - * Confirms the 'invalid argument index number behaviour' for the given command - * targeting a single person in the shown list, using visible index. - * @param commandWord to test assuming it targets a single person in the last shown list based on visible index. - */ - private void assertIndexNotFoundBehaviorForCommand(String commandWord) throws Exception { - String expectedMessage = MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; - TestDataHelper helper = new TestDataHelper(); - List personList = helper.generatePersonList(2); - - // set AB state to 2 persons - model.resetData(new AddressBook()); - for (Person p : personList) { - model.addPerson(p); - } - - assertCommandBehavior(commandWord + " 3", expectedMessage, model.getAddressBook(), personList); - } - - @Test - public void execute_selectInvalidArgsFormat_errorMessageShown() throws Exception { - String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, SelectCommand.MESSAGE_USAGE); - assertIncorrectIndexFormatBehaviorForCommand("select", expectedMessage); - } - - @Test - public void execute_selectIndexNotFound_errorMessageShown() throws Exception { - assertIndexNotFoundBehaviorForCommand("select"); - } - - @Test - public void execute_select_jumpsToCorrectPerson() throws Exception { - TestDataHelper helper = new TestDataHelper(); - List threePersons = helper.generatePersonList(3); - - AddressBook expectedAB = helper.generateAddressBook(threePersons); - helper.addToModel(model, threePersons); - - assertCommandBehavior("select 2", - String.format(SelectCommand.MESSAGE_SELECT_PERSON_SUCCESS, 2), - expectedAB, - expectedAB.getPersonList()); - assertEquals(1, targetedJumpIndex); - assertEquals(model.getFilteredPersonList().get(1), threePersons.get(1)); - } - - - @Test - public void execute_deleteInvalidArgsFormat_errorMessageShown() throws Exception { - String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE); - assertIncorrectIndexFormatBehaviorForCommand("delete", expectedMessage); - } - - @Test - public void execute_deleteIndexNotFound_errorMessageShown() throws Exception { - assertIndexNotFoundBehaviorForCommand("delete"); - } - - @Test - public void execute_delete_removesCorrectPerson() throws Exception { - TestDataHelper helper = new TestDataHelper(); - List threePersons = helper.generatePersonList(3); - - AddressBook expectedAB = helper.generateAddressBook(threePersons); - expectedAB.removePerson(threePersons.get(1)); - helper.addToModel(model, threePersons); - - assertCommandBehavior("delete 2", - String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, threePersons.get(1)), - expectedAB, - expectedAB.getPersonList()); - } - - - @Test - public void execute_find_invalidArgsFormat() throws Exception { - String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE); - assertCommandBehavior("find ", expectedMessage); - } - - @Test - public void execute_find_onlyMatchesFullWordsInNames() throws Exception { - TestDataHelper helper = new TestDataHelper(); - Person pTarget1 = helper.generatePersonWithName("bla bla KEY bla"); - Person pTarget2 = helper.generatePersonWithName("bla KEY bla bceofeia"); - Person p1 = helper.generatePersonWithName("KE Y"); - Person p2 = helper.generatePersonWithName("KEYKEYKEY sduauo"); - - List fourPersons = helper.generatePersonList(p1, pTarget1, p2, pTarget2); - AddressBook expectedAB = helper.generateAddressBook(fourPersons); - List expectedList = helper.generatePersonList(pTarget1, pTarget2); - helper.addToModel(model, fourPersons); - - assertCommandBehavior("find KEY", - Command.getMessageForPersonListShownSummary(expectedList.size()), - expectedAB, - expectedList); - } - - @Test - public void execute_find_isNotCaseSensitive() throws Exception { - TestDataHelper helper = new TestDataHelper(); - Person p1 = helper.generatePersonWithName("bla bla KEY bla"); - Person p2 = helper.generatePersonWithName("bla KEY bla bceofeia"); - Person p3 = helper.generatePersonWithName("key key"); - Person p4 = helper.generatePersonWithName("KEy sduauo"); - - List fourPersons = helper.generatePersonList(p3, p1, p4, p2); - AddressBook expectedAB = helper.generateAddressBook(fourPersons); - List expectedList = fourPersons; - helper.addToModel(model, fourPersons); - - assertCommandBehavior("find KEY", - Command.getMessageForPersonListShownSummary(expectedList.size()), - expectedAB, - expectedList); - } - - @Test - public void execute_find_matchesIfAnyKeywordPresent() throws Exception { - TestDataHelper helper = new TestDataHelper(); - Person pTarget1 = helper.generatePersonWithName("bla bla KEY bla"); - Person pTarget2 = helper.generatePersonWithName("bla rAnDoM bla bceofeia"); - Person pTarget3 = helper.generatePersonWithName("key key"); - Person p1 = helper.generatePersonWithName("sduauo"); - - List fourPersons = helper.generatePersonList(pTarget1, p1, pTarget2, pTarget3); - AddressBook expectedAB = helper.generateAddressBook(fourPersons); - List expectedList = helper.generatePersonList(pTarget1, pTarget2, pTarget3); - helper.addToModel(model, fourPersons); - - assertCommandBehavior("find key rAnDoM", - Command.getMessageForPersonListShownSummary(expectedList.size()), - expectedAB, - expectedList); - } - - - /** - * A utility class to generate test data. - */ - class TestDataHelper{ - - Person adam() throws Exception { - Name name = new Name("Adam Brown"); - Phone privatePhone = new Phone("111111"); - Email email = new Email("adam@gmail.com"); - Address privateAddress = new Address("111, alpha street"); - Tag tag1 = new Tag("tag1"); - Tag tag2 = new Tag("tag2"); - UniqueTagList tags = new UniqueTagList(tag1, tag2); - return new Person(name, privatePhone, email, privateAddress, tags); - } - - /** - * Generates a valid person using the given seed. - * Running this function with the same parameter values guarantees the returned person will have the same state. - * Each unique seed will generate a unique Person object. - * - * @param seed used to generate the person data field values - */ - Person generatePerson(int seed) throws Exception { - return new Person( - new Name("Person " + seed), - new Phone("" + Math.abs(seed)), - new Email(seed + "@email"), - new Address("House of " + seed), - new UniqueTagList(new Tag("tag" + Math.abs(seed)), new Tag("tag" + Math.abs(seed + 1))) - ); - } - - /** Generates the correct add command based on the person given */ - String generateAddCommand(Person p) { - StringBuffer cmd = new StringBuffer(); - - cmd.append("add "); - - cmd.append(p.getName().toString()); - cmd.append(" p/").append(p.getPhone()); - cmd.append(" e/").append(p.getEmail()); - cmd.append(" a/").append(p.getAddress()); - - UniqueTagList tags = p.getTags(); - for(Tag t: tags){ - cmd.append(" t/").append(t.tagName); - } - - return cmd.toString(); - } - - /** - * Generates an AddressBook with auto-generated persons. - */ - AddressBook generateAddressBook(int numGenerated) throws Exception{ - AddressBook addressBook = new AddressBook(); - addToAddressBook(addressBook, numGenerated); - return addressBook; - } - - /** - * Generates an AddressBook based on the list of Persons given. - */ - AddressBook generateAddressBook(List persons) throws Exception{ - AddressBook addressBook = new AddressBook(); - addToAddressBook(addressBook, persons); - return addressBook; - } - - /** - * Adds auto-generated Person objects to the given AddressBook - * @param addressBook The AddressBook to which the Persons will be added - */ - void addToAddressBook(AddressBook addressBook, int numGenerated) throws Exception{ - addToAddressBook(addressBook, generatePersonList(numGenerated)); - } - - /** - * Adds the given list of Persons to the given AddressBook - */ - void addToAddressBook(AddressBook addressBook, List personsToAdd) throws Exception{ - for(Person p: personsToAdd){ - addressBook.addPerson(p); - } - } - - /** - * Adds auto-generated Person objects to the given model - * @param model The model to which the Persons will be added - */ - void addToModel(Model model, int numGenerated) throws Exception{ - addToModel(model, generatePersonList(numGenerated)); - } - - /** - * Adds the given list of Persons to the given model - */ - void addToModel(Model model, List personsToAdd) throws Exception{ - for(Person p: personsToAdd){ - model.addPerson(p); - } - } - - /** - * Generates a list of Persons based on the flags. - */ - List generatePersonList(int numGenerated) throws Exception{ - List persons = new ArrayList<>(); - for(int i = 1; i <= numGenerated; i++){ - persons.add(generatePerson(i)); - } - return persons; - } - - List generatePersonList(Person... persons) { - return Arrays.asList(persons); - } - - /** - * Generates a Person object with given name. Other fields will have some dummy values. - */ - Person generatePersonWithName(String name) throws Exception { - return new Person( - new Name(name), - new Phone("1"), - new Email("1@email"), - new Address("House of 1"), - new UniqueTagList(new Tag("tag")) - ); - } - } -} diff --git a/src/test/java/seedu/address/storage/XmlAddressBookStorageTest.java b/src/test/java/seedu/address/storage/XmlAddressBookStorageTest.java deleted file mode 100644 index 04b0db1ce1c7..000000000000 --- a/src/test/java/seedu/address/storage/XmlAddressBookStorageTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package seedu.address.storage; - - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.commons.util.FileUtil; -import seedu.address.model.AddressBook; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.Person; -import seedu.address.testutil.TypicalTestPersons; - -import java.io.IOException; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -public class XmlAddressBookStorageTest { - private static String TEST_DATA_FOLDER = FileUtil.getPath("./src/test/data/XmlAddressBookStorageTest/"); - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Rule - public TemporaryFolder testFolder = new TemporaryFolder(); - - @Test - public void readAddressBook_nullFilePath_assertionFailure() throws Exception { - thrown.expect(AssertionError.class); - readAddressBook(null); - } - - private java.util.Optional readAddressBook(String filePath) throws Exception { - return new XmlAddressBookStorage(filePath).readAddressBook(addToTestDataPathIfNotNull(filePath)); - } - - private String addToTestDataPathIfNotNull(String prefsFileInTestDataFolder) { - return prefsFileInTestDataFolder != null - ? TEST_DATA_FOLDER + prefsFileInTestDataFolder - : null; - } - - @Test - public void read_missingFile_emptyResult() throws Exception { - assertFalse(readAddressBook("NonExistentFile.xml").isPresent()); - } - - @Test - public void read_notXmlFormat_exceptionThrown() throws Exception { - - thrown.expect(DataConversionException.class); - readAddressBook("NotXmlFormatAddressBook.xml"); - - /* IMPORTANT: Any code below an exception-throwing line (like the one above) will be ignored. - * That means you should not have more than one exception test in one method - */ - } - - @Test - public void readAndSaveAddressBook_allInOrder_success() throws Exception { - String filePath = testFolder.getRoot().getPath() + "TempAddressBook.xml"; - TypicalTestPersons td = new TypicalTestPersons(); - AddressBook original = td.getTypicalAddressBook(); - XmlAddressBookStorage xmlAddressBookStorage = new XmlAddressBookStorage(filePath); - - //Save in new file and read back - xmlAddressBookStorage.saveAddressBook(original, filePath); - ReadOnlyAddressBook readBack = xmlAddressBookStorage.readAddressBook(filePath).get(); - assertEquals(original, new AddressBook(readBack)); - - //Modify data, overwrite exiting file, and read back - original.addPerson(new Person(TypicalTestPersons.hoon)); - original.removePerson(new Person(TypicalTestPersons.alice)); - xmlAddressBookStorage.saveAddressBook(original, filePath); - readBack = xmlAddressBookStorage.readAddressBook(filePath).get(); - assertEquals(original, new AddressBook(readBack)); - - //Save and read without specifying file path - original.addPerson(new Person(TypicalTestPersons.ida)); - xmlAddressBookStorage.saveAddressBook(original); //file path not specified - readBack = xmlAddressBookStorage.readAddressBook().get(); //file path not specified - assertEquals(original, new AddressBook(readBack)); - - } - - @Test - public void saveAddressBook_nullAddressBook_assertionFailure() throws IOException { - thrown.expect(AssertionError.class); - saveAddressBook(null, "SomeFile.xml"); - } - - private void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) throws IOException { - new XmlAddressBookStorage(filePath).saveAddressBook(addressBook, addToTestDataPathIfNotNull(filePath)); - } - - @Test - public void saveAddressBook_nullFilePath_assertionFailure() throws IOException { - thrown.expect(AssertionError.class); - saveAddressBook(new AddressBook(), null); - } - - -} diff --git a/src/test/java/seedu/address/testutil/AddressBookBuilder.java b/src/test/java/seedu/address/testutil/AddressBookBuilder.java deleted file mode 100644 index a623b81c878f..000000000000 --- a/src/test/java/seedu/address/testutil/AddressBookBuilder.java +++ /dev/null @@ -1,35 +0,0 @@ -package seedu.address.testutil; - -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.tag.Tag; -import seedu.address.model.AddressBook; -import seedu.address.model.person.Person; -import seedu.address.model.person.UniquePersonList; - -/** - * A utility class to help with building Addressbook objects. - * Example usage:
- * {@code AddressBook ab = new AddressBookBuilder().withPerson("John", "Doe").withTag("Friend").build();} - */ -public class AddressBookBuilder { - - private AddressBook addressBook; - - public AddressBookBuilder(AddressBook addressBook){ - this.addressBook = addressBook; - } - - public AddressBookBuilder withPerson(Person person) throws UniquePersonList.DuplicatePersonException { - addressBook.addPerson(person); - return this; - } - - public AddressBookBuilder withTag(String tagName) throws IllegalValueException { - addressBook.addTag(new Tag(tagName)); - return this; - } - - public AddressBook build(){ - return addressBook; - } -} diff --git a/src/test/java/seedu/address/testutil/PersonBuilder.java b/src/test/java/seedu/address/testutil/PersonBuilder.java deleted file mode 100644 index 8b02a1668ef6..000000000000 --- a/src/test/java/seedu/address/testutil/PersonBuilder.java +++ /dev/null @@ -1,49 +0,0 @@ -package seedu.address.testutil; - -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.tag.Tag; -import seedu.address.model.person.*; - -/** - * - */ -public class PersonBuilder { - - private TestPerson person; - - public PersonBuilder() { - this.person = new TestPerson(); - } - - public PersonBuilder withName(String name) throws IllegalValueException { - this.person.setName(new Name(name)); - return this; - } - - public PersonBuilder withTags(String ... tags) throws IllegalValueException { - for (String tag: tags) { - person.getTags().add(new Tag(tag)); - } - return this; - } - - public PersonBuilder withAddress(String address) throws IllegalValueException { - this.person.setAddress(new Address(address)); - return this; - } - - public PersonBuilder withPhone(String phone) throws IllegalValueException { - this.person.setPhone(new Phone(phone)); - return this; - } - - public PersonBuilder withEmail(String email) throws IllegalValueException { - this.person.setEmail(new Email(email)); - return this; - } - - public TestPerson build() { - return this.person; - } - -} diff --git a/src/test/java/seedu/address/testutil/TestPerson.java b/src/test/java/seedu/address/testutil/TestPerson.java deleted file mode 100644 index 19ee5ded1cd3..000000000000 --- a/src/test/java/seedu/address/testutil/TestPerson.java +++ /dev/null @@ -1,76 +0,0 @@ -package seedu.address.testutil; - -import seedu.address.model.tag.UniqueTagList; -import seedu.address.model.person.*; - -/** - * A mutable person object. For testing only. - */ -public class TestPerson implements ReadOnlyPerson { - - private Name name; - private Address address; - private Email email; - private Phone phone; - private UniqueTagList tags; - - public TestPerson() { - tags = new UniqueTagList(); - } - - public void setName(Name name) { - this.name = name; - } - - public void setAddress(Address address) { - this.address = address; - } - - public void setEmail(Email email) { - this.email = email; - } - - public void setPhone(Phone phone) { - this.phone = phone; - } - - @Override - public Name getName() { - return name; - } - - @Override - public Phone getPhone() { - return phone; - } - - @Override - public Email getEmail() { - return email; - } - - @Override - public Address getAddress() { - return address; - } - - @Override - public UniqueTagList getTags() { - return tags; - } - - @Override - public String toString() { - return getAsText(); - } - - public String getAddCommand() { - StringBuilder sb = new StringBuilder(); - sb.append("add " + this.getName().fullName + " "); - sb.append("p/" + this.getPhone().value + " "); - sb.append("e/" + this.getEmail().value + " "); - sb.append("a/" + this.getAddress().value + " "); - this.getTags().getInternalList().stream().forEach(s -> sb.append("t/" + s.tagName + " ")); - return sb.toString(); - } -} diff --git a/src/test/java/seedu/address/testutil/TypicalTestPersons.java b/src/test/java/seedu/address/testutil/TypicalTestPersons.java deleted file mode 100644 index 773f64a98cc3..000000000000 --- a/src/test/java/seedu/address/testutil/TypicalTestPersons.java +++ /dev/null @@ -1,61 +0,0 @@ -package seedu.address.testutil; - -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.AddressBook; -import seedu.address.model.person.*; - -/** - * - */ -public class TypicalTestPersons { - - public static TestPerson alice, benson, carl, daniel, elle, fiona, george, hoon, ida; - - public TypicalTestPersons() { - try { - alice = new PersonBuilder().withName("Alice Pauline").withAddress("123, Jurong West Ave 6, #08-111") - .withEmail("alice@gmail.com").withPhone("85355255") - .withTags("friends").build(); - benson = new PersonBuilder().withName("Benson Meier").withAddress("311, Clementi Ave 2, #02-25") - .withEmail("johnd@gmail.com").withPhone("98765432") - .withTags("owesMoney", "friends").build(); - carl = new PersonBuilder().withName("Carl Kurz").withPhone("95352563").withEmail("heinz@yahoo.com").withAddress("wall street").build(); - daniel = new PersonBuilder().withName("Daniel Meier").withPhone("87652533").withEmail("cornelia@google.com").withAddress("10th street").build(); - elle = new PersonBuilder().withName("Elle Meyer").withPhone("9482224").withEmail("werner@gmail.com").withAddress("michegan ave").build(); - fiona = new PersonBuilder().withName("Fiona Kunz").withPhone("9482427").withEmail("lydia@gmail.com").withAddress("little tokyo").build(); - george = new PersonBuilder().withName("George Best").withPhone("9482442").withEmail("anna@google.com").withAddress("4th street").build(); - - //Manually added - hoon = new PersonBuilder().withName("Hoon Meier").withPhone("8482424").withEmail("stefan@mail.com").withAddress("little india").build(); - ida = new PersonBuilder().withName("Ida Mueller").withPhone("8482131").withEmail("hans@google.com").withAddress("chicago ave").build(); - } catch (IllegalValueException e) { - e.printStackTrace(); - assert false : "not possible"; - } - } - - public static void loadAddressBookWithSampleData(AddressBook ab) { - - try { - ab.addPerson(new Person(alice)); - ab.addPerson(new Person(benson)); - ab.addPerson(new Person(carl)); - ab.addPerson(new Person(daniel)); - ab.addPerson(new Person(elle)); - ab.addPerson(new Person(fiona)); - ab.addPerson(new Person(george)); - } catch (UniquePersonList.DuplicatePersonException e) { - assert false : "not possible"; - } - } - - public TestPerson[] getTypicalPersons() { - return new TestPerson[]{alice, benson, carl, daniel, elle, fiona, george}; - } - - public AddressBook getTypicalAddressBook(){ - AddressBook ab = new AddressBook(); - loadAddressBookWithSampleData(ab); - return ab; - } -} diff --git a/src/test/java/seedu/address/TestApp.java b/src/test/java/seedu/malitio/TestApp.java similarity index 71% rename from src/test/java/seedu/address/TestApp.java rename to src/test/java/seedu/malitio/TestApp.java index 756642b6c180..5eb881e8f12d 100644 --- a/src/test/java/seedu/address/TestApp.java +++ b/src/test/java/seedu/malitio/TestApp.java @@ -1,13 +1,14 @@ -package seedu.address; +package seedu.malitio; import javafx.stage.Screen; import javafx.stage.Stage; -import seedu.address.commons.core.Config; -import seedu.address.commons.core.GuiSettings; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.UserPrefs; -import seedu.address.storage.XmlSerializableAddressBook; -import seedu.address.testutil.TestUtil; +import seedu.malitio.testutil.TestUtil; +import seedu.malitio.MainApp; +import seedu.malitio.commons.core.Config; +import seedu.malitio.commons.core.GuiSettings; +import seedu.malitio.model.ReadOnlyMalitio; +import seedu.malitio.model.UserPrefs; +import seedu.malitio.storage.XmlSerializableMalitio; import java.util.function.Supplier; @@ -20,14 +21,14 @@ public class TestApp extends MainApp { public static final String SAVE_LOCATION_FOR_TESTING = TestUtil.getFilePathInSandboxFolder("sampleData.xml"); protected static final String DEFAULT_PREF_FILE_LOCATION_FOR_TESTING = TestUtil.getFilePathInSandboxFolder("pref_testing.json"); public static final String APP_TITLE = "Test App"; - protected static final String ADDRESS_BOOK_NAME = "Test"; - protected Supplier initialDataSupplier = () -> null; + protected static final String MALITIO_NAME = "Test"; + protected Supplier initialDataSupplier = () -> null; protected String saveFileLocation = SAVE_LOCATION_FOR_TESTING; public TestApp() { } - public TestApp(Supplier initialDataSupplier, String saveFileLocation) { + public TestApp(Supplier initialDataSupplier, String saveFileLocation) { super(); this.initialDataSupplier = initialDataSupplier; this.saveFileLocation = saveFileLocation; @@ -35,7 +36,7 @@ public TestApp(Supplier initialDataSupplier, String saveFil // If some initial local data has been provided, write those to the file if (initialDataSupplier.get() != null) { TestUtil.createDataFileWithData( - new XmlSerializableAddressBook(this.initialDataSupplier.get()), + new XmlSerializableMalitio(this.initialDataSupplier.get()), this.saveFileLocation); } } @@ -44,9 +45,9 @@ public TestApp(Supplier initialDataSupplier, String saveFil protected Config initConfig(String configFilePath) { Config config = super.initConfig(configFilePath); config.setAppTitle(APP_TITLE); - config.setAddressBookFilePath(saveFileLocation); + config.setMalitioFilePath(saveFileLocation); config.setUserPrefsFilePath(DEFAULT_PREF_FILE_LOCATION_FOR_TESTING); - config.setAddressBookName(ADDRESS_BOOK_NAME); + config.setMalitioName(MALITIO_NAME); return config; } diff --git a/src/test/java/seedu/address/commons/core/ConfigTest.java b/src/test/java/seedu/malitio/commons/core/ConfigTest.java similarity index 75% rename from src/test/java/seedu/address/commons/core/ConfigTest.java rename to src/test/java/seedu/malitio/commons/core/ConfigTest.java index 62d58646f736..8765ed121ab1 100644 --- a/src/test/java/seedu/address/commons/core/ConfigTest.java +++ b/src/test/java/seedu/malitio/commons/core/ConfigTest.java @@ -1,9 +1,11 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import seedu.malitio.commons.core.Config; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -14,11 +16,11 @@ public class ConfigTest { @Test public void toString_defaultObject_stringReturned() { - String defaultConfigAsString = "App title : Address App\n" + + String defaultConfigAsString = "App title : Malitio\n" + "Current log level : INFO\n" + "Preference file Location : preferences.json\n" + - "Local data file location : data/addressbook.xml\n" + - "AddressBook name : MyAddressBook"; + "Local data file location : data/malitio.xml\n" + + "Malitio name : MyMalitio"; assertEquals(defaultConfigAsString, new Config().toString()); } diff --git a/src/test/java/seedu/address/commons/core/VersionTest.java b/src/test/java/seedu/malitio/commons/core/VersionTest.java similarity index 98% rename from src/test/java/seedu/address/commons/core/VersionTest.java rename to src/test/java/seedu/malitio/commons/core/VersionTest.java index 87ac01f6c92d..1b44f804be6e 100644 --- a/src/test/java/seedu/address/commons/core/VersionTest.java +++ b/src/test/java/seedu/malitio/commons/core/VersionTest.java @@ -1,9 +1,11 @@ -package seedu.address.commons.core; +package seedu.malitio.commons.core; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import seedu.malitio.commons.core.Version; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/seedu/address/commons/util/AppUtilTest.java b/src/test/java/seedu/malitio/commons/util/AppUtilTest.java similarity index 86% rename from src/test/java/seedu/address/commons/util/AppUtilTest.java rename to src/test/java/seedu/malitio/commons/util/AppUtilTest.java index fbea1d0c1e8e..0c4e53cc2f3e 100644 --- a/src/test/java/seedu/address/commons/util/AppUtilTest.java +++ b/src/test/java/seedu/malitio/commons/util/AppUtilTest.java @@ -1,9 +1,11 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import seedu.malitio.commons.util.AppUtil; + import static org.junit.Assert.assertNotNull; public class AppUtilTest { diff --git a/src/test/java/seedu/address/commons/util/ConfigUtilTest.java b/src/test/java/seedu/malitio/commons/util/ConfigUtilTest.java similarity index 92% rename from src/test/java/seedu/address/commons/util/ConfigUtilTest.java rename to src/test/java/seedu/malitio/commons/util/ConfigUtilTest.java index 6699343c4a82..ca112b7844ca 100644 --- a/src/test/java/seedu/address/commons/util/ConfigUtilTest.java +++ b/src/test/java/seedu/malitio/commons/util/ConfigUtilTest.java @@ -1,12 +1,15 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import seedu.address.commons.core.Config; -import seedu.address.commons.exceptions.DataConversionException; + +import seedu.malitio.commons.core.Config; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.commons.util.ConfigUtil; +import seedu.malitio.commons.util.FileUtil; import java.io.File; import java.io.IOException; @@ -76,8 +79,8 @@ private Config getTypicalConfig() { config.setAppTitle("Typical App Title"); config.setLogLevel(Level.INFO); config.setUserPrefsFilePath("C:\\preferences.json"); - config.setAddressBookFilePath("addressbook.xml"); - config.setAddressBookName("TypicalAddressBookName"); + config.setMalitioFilePath("malitio.xml"); + config.setMalitioName("TypicalmalitioName"); return config; } diff --git a/src/test/java/seedu/address/commons/util/FileUtilTest.java b/src/test/java/seedu/malitio/commons/util/FileUtilTest.java similarity index 91% rename from src/test/java/seedu/address/commons/util/FileUtilTest.java rename to src/test/java/seedu/malitio/commons/util/FileUtilTest.java index 8de2621799cf..45c9248ef8d3 100644 --- a/src/test/java/seedu/address/commons/util/FileUtilTest.java +++ b/src/test/java/seedu/malitio/commons/util/FileUtilTest.java @@ -1,11 +1,12 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import seedu.address.testutil.SerializableTestClass; -import seedu.address.testutil.TestUtil; +import seedu.malitio.testutil.SerializableTestClass; +import seedu.malitio.testutil.TestUtil; +import seedu.malitio.commons.util.FileUtil; import java.io.File; import java.io.IOException; diff --git a/src/test/java/seedu/address/commons/util/JsonUtilTest.java b/src/test/java/seedu/malitio/commons/util/JsonUtilTest.java similarity index 85% rename from src/test/java/seedu/address/commons/util/JsonUtilTest.java rename to src/test/java/seedu/malitio/commons/util/JsonUtilTest.java index fc3902188807..ee1162b4289c 100644 --- a/src/test/java/seedu/address/commons/util/JsonUtilTest.java +++ b/src/test/java/seedu/malitio/commons/util/JsonUtilTest.java @@ -1,4 +1,4 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; /** * Tests JSON Read and Write diff --git a/src/test/java/seedu/address/commons/util/StringUtilTest.java b/src/test/java/seedu/malitio/commons/util/StringUtilTest.java similarity index 95% rename from src/test/java/seedu/address/commons/util/StringUtilTest.java rename to src/test/java/seedu/malitio/commons/util/StringUtilTest.java index 194dd71d2c3f..4520729f1092 100644 --- a/src/test/java/seedu/address/commons/util/StringUtilTest.java +++ b/src/test/java/seedu/malitio/commons/util/StringUtilTest.java @@ -1,9 +1,11 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import seedu.malitio.commons.util.StringUtil; + import java.io.FileNotFoundException; import static org.hamcrest.CoreMatchers.containsString; diff --git a/src/test/java/seedu/address/commons/util/UrlUtilTest.java b/src/test/java/seedu/malitio/commons/util/UrlUtilTest.java similarity index 95% rename from src/test/java/seedu/address/commons/util/UrlUtilTest.java rename to src/test/java/seedu/malitio/commons/util/UrlUtilTest.java index 58efab5fd499..eeb40501345d 100644 --- a/src/test/java/seedu/address/commons/util/UrlUtilTest.java +++ b/src/test/java/seedu/malitio/commons/util/UrlUtilTest.java @@ -1,7 +1,9 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import org.junit.Test; +import seedu.malitio.commons.util.UrlUtil; + import java.net.MalformedURLException; import java.net.URL; diff --git a/src/test/java/seedu/address/commons/util/XmlUtilTest.java b/src/test/java/seedu/malitio/commons/util/XmlUtilTest.java similarity index 61% rename from src/test/java/seedu/address/commons/util/XmlUtilTest.java rename to src/test/java/seedu/malitio/commons/util/XmlUtilTest.java index dc4fd886c23e..a94682446d56 100644 --- a/src/test/java/seedu/address/commons/util/XmlUtilTest.java +++ b/src/test/java/seedu/malitio/commons/util/XmlUtilTest.java @@ -1,12 +1,15 @@ -package seedu.address.commons.util; +package seedu.malitio.commons.util; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import seedu.address.model.AddressBook; -import seedu.address.storage.XmlSerializableAddressBook; -import seedu.address.testutil.AddressBookBuilder; -import seedu.address.testutil.TestUtil; + +import seedu.malitio.testutil.MalitioBuilder; +import seedu.malitio.testutil.TestUtil; +import seedu.malitio.commons.util.FileUtil; +import seedu.malitio.commons.util.XmlUtil; +import seedu.malitio.model.Malitio; +import seedu.malitio.storage.XmlSerializableMalitio; import javax.xml.bind.JAXBException; import java.io.File; @@ -19,8 +22,8 @@ public class XmlUtilTest { private static final String TEST_DATA_FOLDER = FileUtil.getPath("src/test/data/XmlUtilTest/"); private static final File EMPTY_FILE = new File(TEST_DATA_FOLDER + "empty.xml"); private static final File MISSING_FILE = new File(TEST_DATA_FOLDER + "missing.xml"); - private static final File VALID_FILE = new File(TEST_DATA_FOLDER + "validAddressBook.xml"); - private static final File TEMP_FILE = new File(TestUtil.getFilePathInSandboxFolder("tempAddressBook.xml")); + private static final File VALID_FILE = new File(TEST_DATA_FOLDER + "validMalitio.xml"); + private static final File TEMP_FILE = new File(TestUtil.getFilePathInSandboxFolder("tempMalitio.xml")); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -28,7 +31,7 @@ public class XmlUtilTest { @Test public void getDataFromFile_nullFile_AssertionError() throws Exception { thrown.expect(AssertionError.class); - XmlUtil.getDataFromFile(null, AddressBook.class); + XmlUtil.getDataFromFile(null, Malitio.class); } @Test @@ -40,26 +43,26 @@ public void getDataFromFile_nullClass_AssertionError() throws Exception { @Test public void getDataFromFile_missingFile_FileNotFoundException() throws Exception { thrown.expect(FileNotFoundException.class); - XmlUtil.getDataFromFile(MISSING_FILE, AddressBook.class); + XmlUtil.getDataFromFile(MISSING_FILE, Malitio.class); } @Test public void getDataFromFile_emptyFile_DataFormatMismatchException() throws Exception { thrown.expect(JAXBException.class); - XmlUtil.getDataFromFile(EMPTY_FILE, AddressBook.class); + XmlUtil.getDataFromFile(EMPTY_FILE, Malitio.class); } @Test public void getDataFromFile_validFile_validResult() throws Exception { - XmlSerializableAddressBook dataFromFile = XmlUtil.getDataFromFile(VALID_FILE, XmlSerializableAddressBook.class); - assertEquals(9, dataFromFile.getPersonList().size()); + XmlSerializableMalitio dataFromFile = XmlUtil.getDataFromFile(VALID_FILE, XmlSerializableMalitio.class); + assertEquals(9, dataFromFile.getFloatingTaskList().size()); assertEquals(0, dataFromFile.getTagList().size()); } @Test public void saveDataToFile_nullFile_AssertionError() throws Exception { thrown.expect(AssertionError.class); - XmlUtil.saveDataToFile(null, new AddressBook()); + XmlUtil.saveDataToFile(null, new Malitio()); } @Test @@ -71,23 +74,23 @@ public void saveDataToFile_nullClass_AssertionError() throws Exception { @Test public void saveDataToFile_missingFile_FileNotFoundException() throws Exception { thrown.expect(FileNotFoundException.class); - XmlUtil.saveDataToFile(MISSING_FILE, new AddressBook()); + XmlUtil.saveDataToFile(MISSING_FILE, new Malitio()); } @Test public void saveDataToFile_validFile_dataSaved() throws Exception { TEMP_FILE.createNewFile(); - XmlSerializableAddressBook dataToWrite = new XmlSerializableAddressBook(new AddressBook()); + XmlSerializableMalitio dataToWrite = new XmlSerializableMalitio(new Malitio()); XmlUtil.saveDataToFile(TEMP_FILE, dataToWrite); - XmlSerializableAddressBook dataFromFile = XmlUtil.getDataFromFile(TEMP_FILE, XmlSerializableAddressBook.class); - assertEquals((new AddressBook(dataToWrite)).toString(),(new AddressBook(dataFromFile)).toString()); + XmlSerializableMalitio dataFromFile = XmlUtil.getDataFromFile(TEMP_FILE, XmlSerializableMalitio.class); + assertEquals((new Malitio(dataToWrite)).toString(),(new Malitio(dataFromFile)).toString()); //TODO: use equality instead of string comparisons - AddressBookBuilder builder = new AddressBookBuilder(new AddressBook()); - dataToWrite = new XmlSerializableAddressBook(builder.withPerson(TestUtil.generateSamplePersonData().get(0)).withTag("Friends").build()); + MalitioBuilder builder = new MalitioBuilder(new Malitio()); + dataToWrite = new XmlSerializableMalitio(builder.withTask(TestUtil.generateSampleTaskData().get(0)).withTag("Friends").build()); XmlUtil.saveDataToFile(TEMP_FILE, dataToWrite); - dataFromFile = XmlUtil.getDataFromFile(TEMP_FILE, XmlSerializableAddressBook.class); - assertEquals((new AddressBook(dataToWrite)).toString(),(new AddressBook(dataFromFile)).toString()); + dataFromFile = XmlUtil.getDataFromFile(TEMP_FILE, XmlSerializableMalitio.class); + assertEquals((new Malitio(dataToWrite)).toString(),(new Malitio(dataFromFile)).toString()); } } diff --git a/src/test/java/seedu/malitio/logic/LogicManagerTest.java b/src/test/java/seedu/malitio/logic/LogicManagerTest.java new file mode 100644 index 000000000000..bfb85f5ba0a8 --- /dev/null +++ b/src/test/java/seedu/malitio/logic/LogicManagerTest.java @@ -0,0 +1,493 @@ +package seedu.malitio.logic; + +import com.google.common.eventbus.Subscribe; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.commons.events.model.MalitioChangedEvent; +import seedu.malitio.commons.events.ui.JumpToListRequestEvent; +import seedu.malitio.commons.events.ui.ShowHelpRequestEvent; +import seedu.malitio.logic.Logic; +import seedu.malitio.logic.LogicManager; +import seedu.malitio.logic.commands.*; +import seedu.malitio.model.Malitio; +import seedu.malitio.model.Model; +import seedu.malitio.model.ModelManager; +import seedu.malitio.model.ReadOnlyMalitio; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.*; +import seedu.malitio.storage.StorageManager; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static seedu.malitio.commons.core.Messages.*; + +public class LogicManagerTest { + + /** + * See https://github.com/junit-team/junit4/wiki/rules#temporaryfolder-rule + */ + @Rule + public TemporaryFolder saveFolder = new TemporaryFolder(); + + private Model model; + private Logic logic; + + //These are for checking the correctness of the events raised + private ReadOnlyMalitio latestSavedMalitio; + private boolean helpShown; + private int targetedJumpIndex; + + @Subscribe + private void handleLocalModelChangedEvent(MalitioChangedEvent abce) { + latestSavedMalitio = new Malitio(abce.data); + } + + @Subscribe + private void handleShowHelpRequestEvent(ShowHelpRequestEvent she) { + helpShown = true; + } + + @Subscribe + private void handleJumpToListRequestEvent(JumpToListRequestEvent je) { + targetedJumpIndex = je.targetIndex; + } + + @Before + public void setup() { + model = new ModelManager(); + String tempmalitioFile = saveFolder.getRoot().getPath() + "Tempmalitio.xml"; + String tempPreferencesFile = saveFolder.getRoot().getPath() + "TempPreferences.json"; + logic = new LogicManager(model, new StorageManager(tempmalitioFile, tempPreferencesFile)); + EventsCenter.getInstance().registerHandler(this); + + latestSavedMalitio = new Malitio(model.getMalitio()); // last saved assumed to be up to date before. + helpShown = false; + targetedJumpIndex = -1; // non yet + } + + @After + public void teardown() { + EventsCenter.clearSubscribers(); + } + + @Test + public void execute_invalid() throws Exception { + String invalidCommand = " "; + assertCommandBehavior(invalidCommand, + String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE)); + } + + /** + * Executes the command and confirms that the result message is correct. + * Both the 'malitio' and the 'last shown list' are expected to be empty. + * @see #assertCommandBehavior(String, String, ReadOnlyMalitio, List) + */ + private void assertCommandBehavior(String inputCommand, String expectedMessage) throws Exception { + assertCommandBehavior(inputCommand, expectedMessage, new Malitio(), Collections.emptyList()); + } + + /** + * Executes the command and confirms that the result message is correct and + * also confirms that the following three parts of the LogicManager object's state are as expected:
+ * - the internal malitio data are same as those in the {@code expectedmalitio}
+ * - the backing list shown by UI matches the {@code shownList}
+ * - {@code expectedmalitio} was saved to the storage file.
+ */ + private void assertCommandBehavior(String inputCommand, String expectedMessage, + ReadOnlyMalitio expectedmalitio, + List expectedShownList) throws Exception { + + //Execute the command + CommandResult result = logic.execute(inputCommand); + + //Confirm the ui display elements should contain the right data + assertEquals(expectedMessage, result.feedbackToUser); + assertEquals(expectedShownList, model.getFilteredFloatingTaskList()); + + //Confirm the state of data (saved and in-memory) is as expected + assertEquals(expectedmalitio, model.getMalitio()); + assertEquals(expectedmalitio, latestSavedMalitio); + } + + + @Test + public void execute_unknownCommandWord() throws Exception { + String unknownCommand = "uicfhmowqewca"; + assertCommandBehavior(unknownCommand, MESSAGE_UNKNOWN_COMMAND); + } + + @Test + public void execute_help() throws Exception { + assertCommandBehavior("help", HelpCommand.SHOWING_HELP_MESSAGE); + assertTrue(helpShown); + } + + @Test + public void execute_exit() throws Exception { + assertCommandBehavior("exit", ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT); + } + + @Test + public void execute_clear() throws Exception { + TestDataHelper helper = new TestDataHelper(); + model.addFloatingTask(helper.generateTask(1)); + model.addFloatingTask(helper.generateTask(2)); + model.addFloatingTask(helper.generateTask(3)); + + assertCommandBehavior("clear", ClearCommand.MESSAGE_SUCCESS, new Malitio(), Collections.emptyList()); + } + + + @Test + public void execute_add_invalidArgsFormat() throws Exception { +// String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE); + assertCommandBehavior( + "add Valid Name p/12345", Name.MESSAGE_NAME_CONSTRAINTS); + } + + @Test + public void execute_add_invalidTask() throws Exception { + assertCommandBehavior( + "add dd//invalid ", Name.MESSAGE_NAME_CONSTRAINTS); + assertCommandBehavior( + "add Valid t/invalid_-[.tag", Tag.MESSAGE_TAG_CONSTRAINTS); + + } + + @Test + public void execute_add_successful() throws Exception { + // setup expectations + TestDataHelper helper = new TestDataHelper(); + FloatingTask toBeAdded = helper.adam(); + Malitio expectedAB = new Malitio(); + expectedAB.addFloatingTask(toBeAdded); + + // execute command and verify result + assertCommandBehavior(helper.generateAddCommand(toBeAdded), + String.format(AddCommand.MESSAGE_SUCCESS, toBeAdded), + expectedAB, + expectedAB.getFloatingTaskList()); + + } + + @Test + public void execute_addDuplicate_notAllowed() throws Exception { + // setup expectations + TestDataHelper helper = new TestDataHelper(); + FloatingTask toBeAdded = helper.adam(); + Malitio expectedAB = new Malitio(); + expectedAB.addFloatingTask(toBeAdded); + + // setup starting state + model.addFloatingTask(toBeAdded); // task already in internal Malitio + + // execute command and verify result + assertCommandBehavior( + helper.generateAddCommand(toBeAdded), + AddCommand.MESSAGE_DUPLICATE_TASK, + expectedAB, + expectedAB.getFloatingTaskList()); + + } + + + @Test + public void execute_list_showsAllTasks() throws Exception { + // prepare expectations + TestDataHelper helper = new TestDataHelper(); + Malitio expectedAB = helper.generateMalitio(2); + List expectedList = expectedAB.getFloatingTaskList(); + + // prepare malitio state + helper.addToModel(model, 2); + + assertCommandBehavior("list", + ListCommand.MESSAGE_SUCCESS, + expectedAB, + expectedList); + } + + + /** + * Confirms the 'invalid argument index number behaviour' for the given command + * targeting a single task in the shown list, using visible index. + * @param commandWord to test assuming it targets a single task in the last shown list based on visible index. + */ + private void assertIncorrectIndexFormatBehaviorForCommand(String commandWord, String expectedMessage) throws Exception { + assertCommandBehavior(commandWord , expectedMessage); //index missing + assertCommandBehavior(commandWord + " +1", expectedMessage); //index should be unsigned + assertCommandBehavior(commandWord + " -1", expectedMessage); //index should be unsigned + assertCommandBehavior(commandWord + " 0", expectedMessage); //index cannot be 0 + assertCommandBehavior(commandWord + " not_a_number", expectedMessage); + } + + /** + * Confirms the 'invalid argument index number behaviour' for the given command + * targeting a single task in the shown list, using visible index. + * @param commandWord to test assuming it targets a single task in the last shown list based on visible index. + */ + private void assertIndexNotFoundBehaviorForCommand(String commandWord) throws Exception { + String expectedMessage = MESSAGE_INVALID_TASK_DISPLAYED_INDEX; + TestDataHelper helper = new TestDataHelper(); + List floatingTaskList = helper.generateFloatingTaskList(2); + + // set AB state to 2 tasks + model.resetData(new Malitio()); + for (FloatingTask p : floatingTaskList) { + model.addFloatingTask(p); + } + + assertCommandBehavior(commandWord + " 3", expectedMessage, model.getMalitio(), floatingTaskList); + } + + @Test + public void execute_selectInvalidArgsFormat_errorMessageShown() throws Exception { + String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, SelectCommand.MESSAGE_USAGE); + assertIncorrectIndexFormatBehaviorForCommand("select", expectedMessage); + } + + @Test + public void execute_selectIndexNotFound_errorMessageShown() throws Exception { + assertIndexNotFoundBehaviorForCommand("select"); + } + + @Test + public void execute_select_jumpsToCorrectTask() throws Exception { + TestDataHelper helper = new TestDataHelper(); + List threeTasks = helper.generateFloatingTaskList(3); + + Malitio expectedAB = helper.generateMalitio(threeTasks); + helper.addToModel(model, threeTasks); + + assertCommandBehavior("select 2", + String.format(SelectCommand.MESSAGE_SELECT_TASK_SUCCESS, 2), + expectedAB, + expectedAB.getFloatingTaskList()); + assertEquals(1, targetedJumpIndex); + assertEquals(model.getFilteredFloatingTaskList().get(1), threeTasks.get(1)); + } + + + @Test + public void execute_deleteInvalidArgsFormat_errorMessageShown() throws Exception { + String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE); + assertIncorrectIndexFormatBehaviorForCommand("delete", expectedMessage); + } + + @Test + public void execute_deleteIndexNotFound_errorMessageShown() throws Exception { + assertIndexNotFoundBehaviorForCommand("delete"); + } + + @Test + public void execute_delete_removesCorrectTask() throws Exception { + TestDataHelper helper = new TestDataHelper(); + List threeTasks = helper.generateFloatingTaskList(3); + + Malitio expectedAB = helper.generateMalitio(threeTasks); + expectedAB.removeTask(threeTasks.get(1)); + helper.addToModel(model, threeTasks); + + assertCommandBehavior("delete 2", + String.format(DeleteCommand.MESSAGE_DELETE_TASK_SUCCESS, threeTasks.get(1)), + expectedAB, + expectedAB.getFloatingTaskList()); + } + + + @Test + public void execute_find_invalidArgsFormat() throws Exception { + String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE); + assertCommandBehavior("find ", expectedMessage); + } + + @Test + public void execute_find_onlyMatchesFullWordsInNames() throws Exception { + TestDataHelper helper = new TestDataHelper(); + FloatingTask pTarget1 = helper.generateTaskWithName("bla bla KEY bla"); + FloatingTask pTarget2 = helper.generateTaskWithName("bla KEY bla bceofeia"); + FloatingTask p1 = helper.generateTaskWithName("KE Y"); + FloatingTask p2 = helper.generateTaskWithName("KEYKEYKEY sduauo"); + + List fourTasks = helper.generateTaskList(p1, pTarget1, p2, pTarget2); + Malitio expectedAB = helper.generateMalitio(fourTasks); + List expectedList = helper.generateTaskList(pTarget1, pTarget2); + helper.addToModel(model, fourTasks); + + assertCommandBehavior("find KEY", + Command.getMessageForTaskListShownSummary(expectedList.size()), + expectedAB, + expectedList); + } + + @Test + public void execute_find_isNotCaseSensitive() throws Exception { + TestDataHelper helper = new TestDataHelper(); + FloatingTask p1 = helper.generateTaskWithName("bla bla KEY bla"); + FloatingTask p2 = helper.generateTaskWithName("bla KEY bla bceofeia"); + FloatingTask p3 = helper.generateTaskWithName("key key"); + FloatingTask p4 = helper.generateTaskWithName("KEy sduauo"); + + List fourTasks = helper.generateTaskList(p3, p1, p4, p2); + Malitio expectedAB = helper.generateMalitio(fourTasks); + List expectedList = fourTasks; + helper.addToModel(model, fourTasks); + + assertCommandBehavior("find KEY", + Command.getMessageForTaskListShownSummary(expectedList.size()), + expectedAB, + expectedList); + } + + @Test + public void execute_find_matchesIfAnyKeywordPresent() throws Exception { + TestDataHelper helper = new TestDataHelper(); + FloatingTask pTarget1 = helper.generateTaskWithName("bla bla KEY bla"); + FloatingTask pTarget2 = helper.generateTaskWithName("bla rAnDoM bla bceofeia"); + FloatingTask pTarget3 = helper.generateTaskWithName("key key"); + FloatingTask p1 = helper.generateTaskWithName("sduauo"); + + List fourTasks = helper.generateTaskList(pTarget1, p1, pTarget2, pTarget3); + Malitio expectedAB = helper.generateMalitio(fourTasks); + List expectedList = helper.generateTaskList(pTarget1, pTarget2, pTarget3); + helper.addToModel(model, fourTasks); + + assertCommandBehavior("find key rAnDoM", + Command.getMessageForTaskListShownSummary(expectedList.size()), + expectedAB, + expectedList); + } + + + /** + * A utility class to generate test data. + */ + class TestDataHelper{ + + FloatingTask adam() throws Exception { + Name task = new Name("Eat lunch"); + Tag tag1 = new Tag("tag1"); + Tag tag2 = new Tag("tag2"); + UniqueTagList tags = new UniqueTagList(tag1, tag2); + return new FloatingTask(task, tags); + } + + /** + * Generates a valid task using the given seed. + * Running this function with the same parameter values guarantees the returned task will have the same state. + * Each unique seed will generate a unique Task object. + * + * @param seed used to generate the task data field values + */ + FloatingTask generateTask(int seed) throws Exception { + return new FloatingTask( + new Name("Task " + seed), + new UniqueTagList(new Tag("tag" + Math.abs(seed)), new Tag("tag" + Math.abs(seed + 1))) + ); + } + + /** Generates the correct add command based on the task given */ + String generateAddCommand(FloatingTask p) { + StringBuffer cmd = new StringBuffer(); + + cmd.append("add "); + + cmd.append(p.getName().toString()); + + UniqueTagList tags = p.getTags(); + for(Tag t: tags){ + cmd.append(" t/").append(t.tagName); + } + + return cmd.toString(); + } + + /** + * Generates Malitio with auto-generated tasks. + */ + Malitio generateMalitio(int numGenerated) throws Exception{ + Malitio malitio = new Malitio(); + addToMalitio(malitio, numGenerated); + return malitio; + } + + /** + * Generates Malitio based on the list of Tasks given. + */ + Malitio generateMalitio(List tasks) throws Exception{ + Malitio malitio = new Malitio(); + addToMalitio(malitio, tasks); + return malitio; + } + + /** + * Adds auto-generated Task objects to the given Malitio + * @param The malitio to which the Tasks will be added + */ + void addToMalitio(Malitio malitio, int numGenerated) throws Exception{ + addToMalitio(malitio, generateFloatingTaskList(numGenerated)); + } + + /** + * Adds the given list of Tasks to the given Malitio + */ + void addToMalitio(Malitio malitio, List tasksToAdd) throws Exception{ + for(FloatingTask p: tasksToAdd){ + malitio.addFloatingTask(p); + } + } + + /** + * Adds auto-generated Task objects to the given model + * @param model The model to which the Tasks will be added + */ + void addToModel(Model model, int numGenerated) throws Exception{ + addToModel(model, generateFloatingTaskList(numGenerated)); + } + + /** + * Adds the given list of Tasks to the given model + */ + void addToModel(Model model, List tasksToAdd) throws Exception{ + for(FloatingTask p: tasksToAdd){ + model.addFloatingTask(p); + } + } + + /** + * Generates a list of Tasks based on the flags. + */ + List generateFloatingTaskList(int numGenerated) throws Exception{ + List tasks = new ArrayList<>(); + for(int i = 1; i <= numGenerated; i++){ + tasks.add(generateTask(i)); + } + return tasks; + } + + List generateTaskList(FloatingTask... floatingtasks) { + return Arrays.asList(floatingtasks); + } + + /** + * Generates a Task object with given name. Other fields will have some dummy values. + */ + FloatingTask generateTaskWithName(String name) throws Exception { + return new FloatingTask( + new Name(name), + new UniqueTagList(new Tag("tag")) + ); + } + } +} diff --git a/src/test/java/seedu/address/model/UnmodifiableObservableListTest.java b/src/test/java/seedu/malitio/model/UnmodifiableObservableListTest.java similarity index 93% rename from src/test/java/seedu/address/model/UnmodifiableObservableListTest.java rename to src/test/java/seedu/malitio/model/UnmodifiableObservableListTest.java index 0334d7e42073..a72cf8b379b3 100644 --- a/src/test/java/seedu/address/model/UnmodifiableObservableListTest.java +++ b/src/test/java/seedu/malitio/model/UnmodifiableObservableListTest.java @@ -1,16 +1,17 @@ -package seedu.address.model; +package seedu.malitio.model; import javafx.collections.FXCollections; +import seedu.malitio.commons.core.UnmodifiableObservableList; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import seedu.address.commons.core.UnmodifiableObservableList; import java.util.*; import static org.junit.Assert.assertSame; -import static seedu.address.testutil.TestUtil.assertThrows; +import static seedu.malitio.testutil.TestUtil.assertThrows; public class UnmodifiableObservableListTest { diff --git a/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java b/src/test/java/seedu/malitio/storage/JsonUserPrefsStorageTest.java similarity index 94% rename from src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java rename to src/test/java/seedu/malitio/storage/JsonUserPrefsStorageTest.java index 4e87203611be..603775260e55 100644 --- a/src/test/java/seedu/address/storage/JsonUserPrefsStorageTest.java +++ b/src/test/java/seedu/malitio/storage/JsonUserPrefsStorageTest.java @@ -1,13 +1,15 @@ -package seedu.address.storage; +package seedu.malitio.storage; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import seedu.address.commons.exceptions.DataConversionException; -import seedu.address.commons.util.FileUtil; -import seedu.address.model.UserPrefs; + +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.commons.util.FileUtil; +import seedu.malitio.model.UserPrefs; +import seedu.malitio.storage.JsonUserPrefsStorage; import java.io.File; import java.io.IOException; diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/malitio/storage/StorageManagerTest.java similarity index 53% rename from src/test/java/seedu/address/storage/StorageManagerTest.java rename to src/test/java/seedu/malitio/storage/StorageManagerTest.java index 6780feab6afc..8e09c925618d 100644 --- a/src/test/java/seedu/address/storage/StorageManagerTest.java +++ b/src/test/java/seedu/malitio/storage/StorageManagerTest.java @@ -1,17 +1,22 @@ -package seedu.address.storage; +package seedu.malitio.storage; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import seedu.address.commons.events.model.AddressBookChangedEvent; -import seedu.address.commons.events.storage.DataSavingExceptionEvent; -import seedu.address.model.AddressBook; -import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.UserPrefs; -import seedu.address.testutil.TypicalTestPersons; -import seedu.address.testutil.EventsCollector; + +import seedu.malitio.testutil.TypicalTestTasks; +import seedu.malitio.commons.events.model.MalitioChangedEvent; +import seedu.malitio.commons.events.storage.DataSavingExceptionEvent; +import seedu.malitio.model.Malitio; +import seedu.malitio.model.ReadOnlyMalitio; +import seedu.malitio.model.UserPrefs; +import seedu.malitio.storage.JsonUserPrefsStorage; +import seedu.malitio.storage.Storage; +import seedu.malitio.storage.StorageManager; +import seedu.malitio.storage.XmlMalitioStorage; +import seedu.malitio.testutil.EventsCollector; import java.io.IOException; @@ -54,25 +59,25 @@ public void prefsReadSave() throws Exception { } @Test - public void addressBookReadSave() throws Exception { - AddressBook original = new TypicalTestPersons().getTypicalAddressBook(); - storageManager.saveAddressBook(original); - ReadOnlyAddressBook retrieved = storageManager.readAddressBook().get(); - assertEquals(original, new AddressBook(retrieved)); - //More extensive testing of AddressBook saving/reading is done in XmlAddressBookStorageTest + public void malitioReadSave() throws Exception { + Malitio original = new TypicalTestTasks().getTypicalMalitio(); + storageManager.savemalitio(original); + ReadOnlyMalitio retrieved = storageManager.readMalitio().get(); + assertEquals(original, new Malitio(retrieved)); + //More extensive testing of malitio saving/reading is done in XmlmalitioStorageTest } @Test - public void getAddressBookFilePath(){ - assertNotNull(storageManager.getAddressBookFilePath()); + public void getmalitioFilePath(){ + assertNotNull(storageManager.getMalitioFilePath()); } @Test - public void handleAddressBookChangedEvent_exceptionThrown_eventRaised() throws IOException { + public void handlemalitioChangedEvent_exceptionThrown_eventRaised() throws IOException { //Create a StorageManager while injecting a stub that throws an exception when the save method is called - Storage storage = new StorageManager(new XmlAddressBookStorageExceptionThrowingStub("dummy"), new JsonUserPrefsStorage("dummy")); + Storage storage = new StorageManager(new XmlmalitioStorageExceptionThrowingStub("dummy"), new JsonUserPrefsStorage("dummy")); EventsCollector eventCollector = new EventsCollector(); - storage.handleAddressBookChangedEvent(new AddressBookChangedEvent(new AddressBook())); + storage.handlemalitioChangedEvent(new MalitioChangedEvent(new Malitio())); assertTrue(eventCollector.get(0) instanceof DataSavingExceptionEvent); } @@ -80,14 +85,14 @@ public void handleAddressBookChangedEvent_exceptionThrown_eventRaised() throws I /** * A Stub class to throw an exception when the save method is called */ - class XmlAddressBookStorageExceptionThrowingStub extends XmlAddressBookStorage{ + class XmlmalitioStorageExceptionThrowingStub extends XmlMalitioStorage{ - public XmlAddressBookStorageExceptionThrowingStub(String filePath) { + public XmlmalitioStorageExceptionThrowingStub(String filePath) { super(filePath); } @Override - public void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) throws IOException { + public void savemalitio(ReadOnlyMalitio malitio, String filePath) throws IOException { throw new IOException("dummy exception"); } } diff --git a/src/test/java/seedu/malitio/storage/XmlMalitioStorageTest.java b/src/test/java/seedu/malitio/storage/XmlMalitioStorageTest.java new file mode 100644 index 000000000000..7efe9f75c5d2 --- /dev/null +++ b/src/test/java/seedu/malitio/storage/XmlMalitioStorageTest.java @@ -0,0 +1,107 @@ +package seedu.malitio.storage; + + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; + +import seedu.malitio.testutil.TypicalTestTasks; +import seedu.malitio.commons.exceptions.DataConversionException; +import seedu.malitio.commons.util.FileUtil; +import seedu.malitio.model.Malitio; +import seedu.malitio.model.ReadOnlyMalitio; +import seedu.malitio.model.task.FloatingTask; +import seedu.malitio.storage.XmlMalitioStorage; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +public class XmlMalitioStorageTest { + private static String TEST_DATA_FOLDER = FileUtil.getPath("./src/test/data/XmlMalitioStorageTest/"); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public TemporaryFolder testFolder = new TemporaryFolder(); + + @Test + public void readmalitio_nullFilePath_assertionFailure() throws Exception { + thrown.expect(AssertionError.class); + readMalitio(null); + } + + private java.util.Optional readMalitio(String filePath) throws Exception { + return new XmlMalitioStorage(filePath).readMalitio(addToTestDataPathIfNotNull(filePath)); + } + + private String addToTestDataPathIfNotNull(String prefsFileInTestDataFolder) { + return prefsFileInTestDataFolder != null + ? TEST_DATA_FOLDER + prefsFileInTestDataFolder + : null; + } + + @Test + public void read_missingFile_emptyResult() throws Exception { + assertFalse(readMalitio("NonExistentFile.xml").isPresent()); + } + + @Test + public void read_notXmlFormat_exceptionThrown() throws Exception { + + thrown.expect(DataConversionException.class); + readMalitio("NotXmlFormatMalitio.xml"); + + /* IMPORTANT: Any code below an exception-throwing line (like the one above) will be ignored. + * That means you should not have more than one exception test in one method + */ + } + + @Test + public void readAndSavemalitio_allInOrder_success() throws Exception { + String filePath = testFolder.getRoot().getPath() + "Tempmalitio.xml"; + TypicalTestTasks td = new TypicalTestTasks(); + Malitio original = td.getTypicalMalitio(); + XmlMalitioStorage xmlmalitioStorage = new XmlMalitioStorage(filePath); + + //Save in new file and read back + xmlmalitioStorage.savemalitio(original, filePath); + ReadOnlyMalitio readBack = xmlmalitioStorage.readMalitio(filePath).get(); + assertEquals(original, new Malitio(readBack)); + + //Modify data, overwrite exiting file, and read back + original.addFloatingTask(new FloatingTask(TypicalTestTasks.manualFloatingTask)); + original.removeTask(new FloatingTask(TypicalTestTasks.floatingTask1)); + xmlmalitioStorage.savemalitio(original, filePath); + readBack = xmlmalitioStorage.readMalitio(filePath).get(); + assertEquals(original, new Malitio(readBack)); + + //Save and read without specifying file path + original.addFloatingTask(new FloatingTask(TypicalTestTasks.manualDeadline)); + xmlmalitioStorage.savemalitio(original); //file path not specified + readBack = xmlmalitioStorage.readMalitio().get(); //file path not specified + assertEquals(original, new Malitio(readBack)); + + } + + @Test + public void savemalitio_nullmalitio_assertionFailure() throws IOException { + thrown.expect(AssertionError.class); + savemalitio(null, "SomeFile.xml"); + } + + private void savemalitio(ReadOnlyMalitio malitio, String filePath) throws IOException { + new XmlMalitioStorage(filePath).savemalitio(malitio, addToTestDataPathIfNotNull(filePath)); + } + + @Test + public void savemalitio_nullFilePath_assertionFailure() throws IOException { + thrown.expect(AssertionError.class); + savemalitio(new Malitio(), null); + } + + +} diff --git a/src/test/java/seedu/address/testutil/EventsCollector.java b/src/test/java/seedu/malitio/testutil/EventsCollector.java similarity index 85% rename from src/test/java/seedu/address/testutil/EventsCollector.java rename to src/test/java/seedu/malitio/testutil/EventsCollector.java index c44d6ca6f95a..1d986fff42b0 100644 --- a/src/test/java/seedu/address/testutil/EventsCollector.java +++ b/src/test/java/seedu/malitio/testutil/EventsCollector.java @@ -1,8 +1,9 @@ -package seedu.address.testutil; +package seedu.malitio.testutil; import com.google.common.eventbus.Subscribe; -import seedu.address.commons.core.EventsCenter; -import seedu.address.commons.events.BaseEvent; + +import seedu.malitio.commons.core.EventsCenter; +import seedu.malitio.commons.events.BaseEvent; import java.util.ArrayList; import java.util.List; diff --git a/src/test/java/seedu/malitio/testutil/MalitioBuilder.java b/src/test/java/seedu/malitio/testutil/MalitioBuilder.java new file mode 100644 index 000000000000..cba414756d62 --- /dev/null +++ b/src/test/java/seedu/malitio/testutil/MalitioBuilder.java @@ -0,0 +1,36 @@ +package seedu.malitio.testutil; + +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.Malitio; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.task.FloatingTask; +import seedu.malitio.model.task.ReadOnlyFloatingTask; +import seedu.malitio.model.task.UniqueFloatingTaskList; + +/** + * A utility class to help with building malitio objects. + * Example usage:
+ * {@code malitio ab = new malitioBuilder().withTask("Eat", "Sleep").withTag("Friend").build();} + */ +public class MalitioBuilder { + + private Malitio malitio; + + public MalitioBuilder(Malitio malitio) { + this.malitio = malitio; + } + + public MalitioBuilder withTask(FloatingTask task) throws UniqueFloatingTaskList.DuplicateFloatingTaskException { + malitio.addFloatingTask(task); + return this; + } + + public MalitioBuilder withTag(String tagName) throws IllegalValueException { + malitio.addTag(new Tag(tagName)); + return this; + } + + public Malitio build(){ + return malitio; + } +} diff --git a/src/test/java/seedu/address/testutil/SerializableTestClass.java b/src/test/java/seedu/malitio/testutil/SerializableTestClass.java similarity index 98% rename from src/test/java/seedu/address/testutil/SerializableTestClass.java rename to src/test/java/seedu/malitio/testutil/SerializableTestClass.java index ef58ef857179..a8d52969b266 100644 --- a/src/test/java/seedu/address/testutil/SerializableTestClass.java +++ b/src/test/java/seedu/malitio/testutil/SerializableTestClass.java @@ -1,4 +1,4 @@ -package seedu.address.testutil; +package seedu.malitio.testutil; import java.time.LocalDateTime; import java.util.ArrayList; diff --git a/src/test/java/seedu/malitio/testutil/TaskBuilder.java b/src/test/java/seedu/malitio/testutil/TaskBuilder.java new file mode 100644 index 000000000000..0dd4e7198b19 --- /dev/null +++ b/src/test/java/seedu/malitio/testutil/TaskBuilder.java @@ -0,0 +1,48 @@ +package seedu.malitio.testutil; + +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.task.*; + +/** + * + */ +public class TaskBuilder { + + private TestTask Task; + + public TaskBuilder() { + this.Task = new TestTask(); + } + + public TaskBuilder withName(String name) throws IllegalValueException { + this.Task.setName(new Name(name)); + return this; + } + + public TaskBuilder dueOn(String due) throws IllegalValueException { + this.Task.setDue(new DateTime(due)); + return this; + } + + public TaskBuilder start(String start) throws IllegalValueException { + this.Task.setStart(new DateTime(start)); + return this; + } + public TaskBuilder end(String end) throws IllegalValueException { + this.Task.setEnd(new DateTime(end)); + return this; + } + + public TaskBuilder withTags(String ... tags) throws IllegalValueException { + for (String tag: tags) { + Task.getTags().add(new Tag(tag)); + } + return this; + } + + public TestTask build() { + return this.Task; + } + +} diff --git a/src/test/java/seedu/malitio/testutil/TestTask.java b/src/test/java/seedu/malitio/testutil/TestTask.java new file mode 100644 index 000000000000..8f5dda32c403 --- /dev/null +++ b/src/test/java/seedu/malitio/testutil/TestTask.java @@ -0,0 +1,84 @@ +package seedu.malitio.testutil; + +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.*; + +/** + * A mutable task object. For testing only. + */ +public class TestTask implements ReadOnlyFloatingTask, ReadOnlyDeadline, ReadOnlyEvent { + + private Name name; + private DateTime due; + private DateTime start; + private DateTime end; + private UniqueTagList tags; + + public TestTask() { + tags = new UniqueTagList(); + } + + public void setName(Name name) { + this.name = name; + } + + @Override + public Name getName() { + return name; + } + + @Override + public UniqueTagList getTags() { + return tags; + } + + @Override + public String toString() { + return getAsText(); + } + + public String getAddCommand() { + StringBuilder sb = new StringBuilder(); + sb.append("add " + this.getName().fullName + " "); + this.getTags().getInternalList().stream().forEach(s -> sb.append("t/" + s.tagName + " ")); + return sb.toString(); + } + + + public DateTime getDue() { + return due; + } + + + public void setDue(DateTime due) { + this.due = due; + } + + public DateTime getStart() { + return start; + } + + public void setStart(DateTime start) { + this.start = start; + } + + public DateTime getEnd() { + return end; + } + + public void setEnd(DateTime end) { + this.end = end; + } + + @Override + public String tagsString() { + // TODO Auto-generated method stub + return ReadOnlyDeadline.super.tagsString(); + } + + @Override + public String getAsText() { + return ReadOnlyFloatingTask.super.getAsText(); + } + +} diff --git a/src/test/java/seedu/address/testutil/TestUtil.java b/src/test/java/seedu/malitio/testutil/TestUtil.java similarity index 67% rename from src/test/java/seedu/address/testutil/TestUtil.java rename to src/test/java/seedu/malitio/testutil/TestUtil.java index 17c92d66398a..557103038a9b 100644 --- a/src/test/java/seedu/address/testutil/TestUtil.java +++ b/src/test/java/seedu/malitio/testutil/TestUtil.java @@ -1,7 +1,7 @@ -package seedu.address.testutil; +package seedu.malitio.testutil; import com.google.common.io.Files; -import guitests.guihandles.PersonCardHandle; +import guitests.guihandles.TaskCardHandle; import javafx.geometry.Bounds; import javafx.geometry.Point2D; import javafx.scene.Node; @@ -12,15 +12,15 @@ import junit.framework.AssertionFailedError; import org.loadui.testfx.GuiTest; import org.testfx.api.FxToolkit; -import seedu.address.TestApp; -import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.commons.util.FileUtil; -import seedu.address.commons.util.XmlUtil; -import seedu.address.model.AddressBook; -import seedu.address.model.person.*; -import seedu.address.model.tag.Tag; -import seedu.address.model.tag.UniqueTagList; -import seedu.address.storage.XmlSerializableAddressBook; +import seedu.malitio.TestApp; +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.commons.util.FileUtil; +import seedu.malitio.commons.util.XmlUtil; +import seedu.malitio.model.Malitio; +import seedu.malitio.model.tag.Tag; +import seedu.malitio.model.tag.UniqueTagList; +import seedu.malitio.model.task.*; +import seedu.malitio.storage.XmlSerializableMalitio; import java.io.File; import java.io.IOException; @@ -60,20 +60,22 @@ public static void assertThrows(Class expected, Runnable ex */ public static String SANDBOX_FOLDER = FileUtil.getPath("./src/test/data/sandbox/"); - public static final Person[] samplePersonData = getSamplePersonData(); - - private static Person[] getSamplePersonData() { + public static final FloatingTask[] sampleFloatingTaskData = getSampleTaskData(); + public static final Deadline[] sampleDeadlineData = getSampleDeadlineData(); + public static final Event[] sampleEventData = getSampleEventData(); + + private static FloatingTask[] getSampleTaskData() { try { - return new Person[]{ - new Person(new Name("Ali Muster"), new Phone("9482424"), new Email("hans@google.com"), new Address("4th street"), new UniqueTagList()), - new Person(new Name("Boris Mueller"), new Phone("87249245"), new Email("ruth@google.com"), new Address("81th street"), new UniqueTagList()), - new Person(new Name("Carl Kurz"), new Phone("95352563"), new Email("heinz@yahoo.com"), new Address("wall street"), new UniqueTagList()), - new Person(new Name("Daniel Meier"), new Phone("87652533"), new Email("cornelia@google.com"), new Address("10th street"), new UniqueTagList()), - new Person(new Name("Elle Meyer"), new Phone("9482224"), new Email("werner@gmail.com"), new Address("michegan ave"), new UniqueTagList()), - new Person(new Name("Fiona Kunz"), new Phone("9482427"), new Email("lydia@gmail.com"), new Address("little tokyo"), new UniqueTagList()), - new Person(new Name("George Best"), new Phone("9482442"), new Email("anna@google.com"), new Address("4th street"), new UniqueTagList()), - new Person(new Name("Hoon Meier"), new Phone("8482424"), new Email("stefan@mail.com"), new Address("little india"), new UniqueTagList()), - new Person(new Name("Ida Mueller"), new Phone("8482131"), new Email("hans@google.com"), new Address("chicago ave"), new UniqueTagList()) + return new FloatingTask[]{ + new FloatingTask(new Name("adjust meter"), new UniqueTagList()), + new FloatingTask(new Name("bring along notes"), new UniqueTagList()), + new FloatingTask(new Name("copy answer"), new UniqueTagList()), + new FloatingTask(new Name("do some sit-up"), new UniqueTagList()), + new FloatingTask(new Name("eat with mom"), new UniqueTagList()), + new FloatingTask(new Name("forgive and forget"), new UniqueTagList()), + new FloatingTask(new Name("go shopping"), new UniqueTagList()), + new FloatingTask(new Name("hopping"), new UniqueTagList()), + new FloatingTask(new Name("Ida Mueller"), new UniqueTagList()) }; } catch (IllegalValueException e) { assert false; @@ -82,6 +84,16 @@ private static Person[] getSamplePersonData() { } } + private static Event[] getSampleEventData() { + // TODO Auto-generated method stub + return null; + } + + private static Deadline[] getSampleDeadlineData() { + // TODO Auto-generated method stub + return null; + } + public static final Tag[] sampleTagData = getSampleTagData(); private static Tag[] getSampleTagData() { @@ -97,8 +109,8 @@ private static Tag[] getSampleTagData() { } } - public static List generateSamplePersonData() { - return Arrays.asList(samplePersonData); + public static List generateSampleTaskData() { + return Arrays.asList(sampleFloatingTaskData); } /** @@ -117,7 +129,7 @@ public static String getFilePathInSandboxFolder(String fileName) { } public static void createDataFileWithSampleData(String filePath) { - createDataFileWithData(generateSampleStorageAddressBook(), filePath); + createDataFileWithData(generateSampleStoragemalitio(), filePath); } public static void createDataFileWithData(T data, String filePath) { @@ -134,12 +146,13 @@ public static void main(String... s) { createDataFileWithSampleData(TestApp.SAVE_LOCATION_FOR_TESTING); } - public static AddressBook generateEmptyAddressBook() { - return new AddressBook(new UniquePersonList(), new UniqueTagList()); + public static Malitio generateEmptymalitio() { + return new Malitio(new UniqueFloatingTaskList(), new UniqueDeadlineList(), + new UniqueEventList(), new UniqueTagList()); } - public static XmlSerializableAddressBook generateSampleStorageAddressBook() { - return new XmlSerializableAddressBook(generateEmptyAddressBook()); + public static XmlSerializableMalitio generateSampleStoragemalitio() { + return new XmlSerializableMalitio(generateEmptymalitio()); } /** @@ -273,49 +286,49 @@ public static Object getLastElement(List list) { } /** - * Removes a subset from the list of persons. - * @param persons The list of persons - * @param personsToRemove The subset of persons. - * @return The modified persons after removal of the subset from persons. + * Removes a subset from the list of tasks. + * @param tasks The list of tasks + * @param tasksToRemove The subset of tasks. + * @return The modified tasks after removal of the subset from tasks. */ - public static TestPerson[] removePersonsFromList(final TestPerson[] persons, TestPerson... personsToRemove) { - List listOfPersons = asList(persons); - listOfPersons.removeAll(asList(personsToRemove)); - return listOfPersons.toArray(new TestPerson[listOfPersons.size()]); + public static TestTask[] removeTasksFromList(final TestTask[] tasks, TestTask... tasksToRemove) { + List listOfTasks = asList(tasks); + listOfTasks.removeAll(asList(tasksToRemove)); + return listOfTasks.toArray(new TestTask[listOfTasks.size()]); } /** - * Returns a copy of the list with the person at specified index removed. + * Returns a copy of the list with the task at specified index removed. * @param list original list to copy from * @param targetIndexInOneIndexedFormat e.g. if the first element to be removed, 1 should be given as index. */ - public static TestPerson[] removePersonFromList(final TestPerson[] list, int targetIndexInOneIndexedFormat) { - return removePersonsFromList(list, list[targetIndexInOneIndexedFormat-1]); + public static TestTask[] removeTaskFromList(final TestTask[] list, int targetIndexInOneIndexedFormat) { + return removeTasksFromList(list, list[targetIndexInOneIndexedFormat-1]); } /** - * Replaces persons[i] with a person. - * @param persons The array of persons. - * @param person The replacement person - * @param index The index of the person to be replaced. + * Replaces tasks[i] with a task. + * @param tasks The array of tasks. + * @param task The replacement task + * @param index The index of the task to be replaced. * @return */ - public static TestPerson[] replacePersonFromList(TestPerson[] persons, TestPerson person, int index) { - persons[index] = person; - return persons; + public static TestTask[] replaceTaskFromList(TestTask[] tasks, TestTask task, int index) { + tasks[index] = task; + return tasks; } /** - * Appends persons to the array of persons. - * @param persons A array of persons. - * @param personsToAdd The persons that are to be appended behind the original array. - * @return The modified array of persons. + * Appends tasks to the array of tasks. + * @param tasks A array of tasks. + * @param tasksToAdd The tasks that are to be appended behind the original array. + * @return The modified array of tasks. */ - public static TestPerson[] addPersonsToList(final TestPerson[] persons, TestPerson... personsToAdd) { - List listOfPersons = asList(persons); - listOfPersons.addAll(asList(personsToAdd)); - return listOfPersons.toArray(new TestPerson[listOfPersons.size()]); + public static TestTask[] addTasksToList(final TestTask[] tasks, TestTask... tasksToAdd) { + List listOfTasks = asList(tasks); + listOfTasks.addAll(asList(tasksToAdd)); + return listOfTasks.toArray(new TestTask[listOfTasks.size()]); } private static List asList(T[] objs) { @@ -326,8 +339,8 @@ private static List asList(T[] objs) { return list; } - public static boolean compareCardAndPerson(PersonCardHandle card, ReadOnlyPerson person) { - return card.isSamePerson(person); + public static boolean compareCardAndTask(TaskCardHandle card, ReadOnlyFloatingTask task) { + return card.isSameTask(task); } public static Tag[] getTagList(String tags) { diff --git a/src/test/java/seedu/malitio/testutil/TypicalTestTasks.java b/src/test/java/seedu/malitio/testutil/TypicalTestTasks.java new file mode 100644 index 000000000000..3f0be6e7fd7d --- /dev/null +++ b/src/test/java/seedu/malitio/testutil/TypicalTestTasks.java @@ -0,0 +1,61 @@ +package seedu.malitio.testutil; + +import seedu.malitio.commons.exceptions.DuplicateDataException; +import seedu.malitio.commons.exceptions.IllegalValueException; +import seedu.malitio.model.Malitio; +import seedu.malitio.model.task.*; + +/** + * + */ +public class TypicalTestTasks { + + public static TestTask floatingTask1, floatingTask2, deadline1, deadline2, event1, event2, event3, event4, manualFloatingTask, manualDeadline; + + public TypicalTestTasks() { + try { + floatingTask1 = new TaskBuilder().withName("adjust meter") + .withTags("careful").build(); + floatingTask2 = new TaskBuilder().withName("bring along notes") + .withTags("pen", "cs2103").build(); + deadline1 = new TaskBuilder().withName("copy answer").build(); + deadline2 = new TaskBuilder().withName("do some sit-up").build(); + event1 = new TaskBuilder().withName("eat with mom").build(); + event2 = new TaskBuilder().withName("forgive with forget").build(); + event3 = new TaskBuilder().withName("go shopping").build(); + event4 = new TaskBuilder().withName("hopping").build(); + + //Manually added + manualFloatingTask = new TaskBuilder().withName("spa relaxation").build(); + manualDeadline = new TaskBuilder().withName("prepare for interview").build(); + } catch (IllegalValueException e) { + e.printStackTrace(); + assert false : "not possible"; + } + } + + public static void loadmalitioWithSampleData(Malitio ab) { + + try { + ab.addFloatingTask(new FloatingTask(floatingTask1)); + ab.addFloatingTask(new FloatingTask(floatingTask2)); + ab.addFloatingTask(new FloatingTask(deadline1)); + ab.addFloatingTask(new FloatingTask(deadline2)); + ab.addFloatingTask(new FloatingTask(event1)); + ab.addFloatingTask(new FloatingTask(event2)); + ab.addFloatingTask(new FloatingTask(event3)); + } catch (DuplicateDataException e) { + assert false : "not possible"; + } + } + + public TestTask[] getTypicalTasks() { + return new TestTask[]{floatingTask1, floatingTask2, deadline1, deadline2, event1, event2, event3}; + } + + public Malitio getTypicalMalitio(){ + Malitio ab = new Malitio(); + loadmalitioWithSampleData(ab); + return ab; + } +}